home *** CD-ROM | disk | FTP | other *** search
/ Groovy Bytes: Behind the Moon / groovybytes.iso / GROOVY / SND_TOOL / FUNK108A.ZIP / DOS32V30.ZIP / LIB / GUS.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-06-11  |  26.8 KB  |  792 lines

  1. ;--------------------------------------------------------------------------;
  2. ;    DOS32    32BIT  DOS  EXTENDER  LIBRARY  Gravis Ultrasound Routines    ;
  3. ;                                                                          ;
  4. ; Written by Adam Seychell                                                 ;
  5. ;                                                                          ;
  6. ;                                                                          ;
  7. ;  Last modified    8rd April 1995                                         ;
  8. ;                                                                          ;
  9. ;--------------------------------------------------------------------------;
  10. ; Note  The "GF1" is the Ultrasounds programable Synthesizer chip for the
  11. ;  32 multi-timbral digital 16bit CD quality voices with independed volume
  12. ;  ramping, panning and smapling rate.
  13. ;
  14. .386
  15. .Model flat
  16. .Code
  17.  
  18.  
  19. Include GUS.INC                       ; Define all the publics symbols
  20.  
  21.  
  22. outp    MACRO port,value
  23.         mov     al,value
  24.         mov     edx,dword ptr port
  25.         out     dx,al
  26. ENDM
  27.  
  28. FALSE    equ    0
  29. TRUE     equ     1
  30.  
  31.  
  32. ;╒═════════════════════════════════════════════════════════════════════════╕
  33. ;│           THE GRAVIS UILTRASOUND PORT ADDRESS VARIBLES                  │
  34. ;│                                                                         │
  35. ;│  These 12 data vaibles below contian the ultrasounds port addresses.    │
  36. ;│  See the SDK for what each port does. These varibles will be initalized │
  37. ;│  on the first successful call to the Ultrasound_Reset routine in this   │
  38. ;│  library.                                                               │
  39. ;│  * Do not use these port address varibles until they are initalized as  │
  40. ;│  otherwise they will contian wrong values.                              │
  41. ;└─────────────────────────────────────────────────────────────────────────┘
  42. align 4
  43.     The_Ultrasound_port_Addresses                               LABEL dword
  44. GF1_Voice_Select        dw  102h        ; GF1 Synthesizer
  45. GF1_REG_Select          dw  103h
  46. GF1_Data_Low            dw  104h
  47. GF1_Data_High           dw  105h
  48. GF1_IRQ_status          dw  006h
  49. GF1_DRAM                dw  107h
  50. GF1_TIMER_Ctrl          dw  008h
  51. GF1_TIMER_Data          dw  009h
  52. Midi_control            dw  100h        ; MIDI Interface
  53. Midi_Data               dw  101h
  54. Mix_control             dw  000h        ; BOARD CONTROL ONLY
  55. IRQDMA_Ctrl             dw  00Bh
  56. Ultrasound_ports_ends                                          LABEL dword
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. dma_reg_list            db  0,1,0,2,0,3,4,5
  65. irq_reg_list            db  0,0,1,3,0,2,0,4,0,0,0,5,6,0,0,7
  66. GUS_Base_port           dw  0h
  67. ULTRASND_string         db 'ULTRASND='
  68. GUSdetected_flag        db  False
  69.  
  70.  
  71. ;╒═════════════════════════════════════════════════════════════════════════╕
  72. ;│           GET THE DEFAULT SETTING OF THE GRAVIS UILTRASOUND             │
  73. ;│                                                                         │
  74. ;│                                                                         │
  75. ;│  Looks for the environment varible "ULTRASND" for the default settings  │
  76. ;│  of the Ultrasound.                                                     │
  77. ;│                                                                         │
  78. ;│   IN:  nothing                                                          │
  79. ;│                                                                         │
  80. ;│  OUT:   Carry is set if couldn't find environment or it has invalid     │
  81. ;│         settings.                                                       │
  82. ;│                                                                         │
  83. ;│         Otherwise the carry flag is cleared and;                        │
  84. ;│      BL = GF1  IRQ number  ( IRQ is either 0,2,3,5,7,11,12 or 15 )      │
  85. ;│      BH = MIDI IRQ number                                               │
  86. ;│      CL = DMA Playback channel  ( DMA is either 0,1,3,5,6 or 7 )        │
  87. ;│      CH = DMA Record channel                                            │
  88. ;│      DX = Port Address ( 210h,220h,230h,240h,250h or 260h )             │
  89. ;│                                                                         │
  90. ;└─────────────────────────────────────────────────────────────────────────┘
  91. GetUltraConfig PROC
  92.  
  93. local   Base_port       :WORD
  94. local   dma_control     :BYTE
  95. local   irq_control     :BYTE
  96.  
  97.         push     Eax
  98.         push     Edi
  99.     ;
  100.     ; Search for the string "ULTRASND="  in the environment area
  101.     ;
  102.         Mov     Ax,0EE02h
  103.         Int     31h                             ; Returns EDI -> environment
  104.         cld
  105. Loop_Envir:
  106.         Mov     esi,Offset ULTRASND_string
  107.         mov     ecx,9
  108.         repe    cmpsb
  109.         je   Found_string
  110.         xor     al,al
  111.         repne   scasb
  112.         cmp     byte ptr [edi],0
  113.         jne  Loop_Envir
  114.         jmp  No_ULTRASND
  115.  
  116.  
  117. Found_string:                       ; EDI -> first char of string
  118.  
  119.  
  120.         mov     ebx,[edi]              ; OK, Found the string 'ULTRASND='
  121.         mov     eax,ebx                ; check for the valid paramters
  122.         and     ebx,0ffff00ffh
  123.         cmp     ebx,02C300032h         ; '2x0,'
  124.         jne  No_ULTRASND
  125.         shr     eax,8
  126.         call    get_digit               ; eax = char digit in al
  127.         mov     DX,ax                   ; load port address
  128.         shl     edx,4
  129.         add     dx,200h
  130.         sub     al,1h          ; port must be between  210h .. 260h
  131.         cmp     al,5h
  132.         ja  No_ULTRASND
  133.         add     edi,4
  134.  
  135.                         ;*****  Get playback DMA channel ****
  136.         xor     ecx,ecx
  137.         mov     al,[edi]
  138.         call    get_digit
  139.         cmp     dma_reg_list[eax],0
  140.         je  No_ULTRASND
  141.         mov     CL,AL
  142.         inc     edi
  143.         cmp     byte ptr [edi],','
  144.         jne  No_ULTRASND
  145.  
  146.                         ;*****  Get record DMA channel  ****
  147.         inc     edi
  148.         mov     al,[edi]
  149.         call    get_digit
  150.         cmp     dma_reg_list[eax],0
  151.         je  No_ULTRASND
  152.         mov     CH,AL
  153.         inc     edi
  154.         cmp     byte ptr [edi],','
  155.         jne  No_ULTRASND
  156.  
  157.                     ; **** Get IRQ numnber GF1 ****
  158.         xor     ebx,ebx
  159.         inc     edi
  160.         cmp     byte ptr [edi],'1'
  161.         jne J61
  162.           mov    BL,10
  163.           inc    edi
  164. J61:    mov     al,[edi]
  165.         call    get_digit
  166.         add     al,bl
  167.         cmp     al,15
  168.         ja  No_ULTRASND
  169.         cmp     IRQ_reg_list[eax],0         ; check for valid IRQ number
  170.         je  No_ULTRASND
  171.         mov     BL,AL
  172.         inc     edi
  173.         cmp     byte ptr [edi],','
  174.         jne  No_ULTRASND
  175.  
  176.                      ;  **** Get MIDI IRQ numnber *****
  177.  
  178.         inc     edi
  179.         cmp     byte ptr [edi],'1'
  180.         jne J62
  181.          mov    BH,10
  182.          inc    edi
  183. J62:     mov     al,[edi]
  184.         call    get_digit
  185.         add     al,bh
  186.         cmp     al,15
  187.         ja  No_ULTRASND
  188.         cmp     IRQ_reg_list[eax],0         ; check for valid IRQ number
  189.         je  No_ULTRASND
  190.         mov     BH,AL
  191.                                                 ;CHECK FOR STRING ENDING
  192.         inc     edi
  193.         cmp     byte ptr [edi],','
  194.         je got_it
  195.         cmp     byte ptr [edi],' '
  196.         je got_it
  197.         cmp     byte ptr [edi],0
  198.         jne  No_ULTRASND
  199.  
  200. got_it:
  201.         clc
  202.         Pop    Edi
  203.         Pop    Eax
  204.         ret
  205.  
  206.  
  207. No_ULTRASND:
  208.         stc
  209.         Pop    Edi
  210.         Pop    Eax
  211.         ret
  212.  
  213.  
  214. get_digit:
  215.         sub     al,'0'
  216.         jc No_digi
  217.         cmp     al,9
  218.         ja No_digi
  219.         movzx   eax,al
  220.         ret 0
  221. No_digi:
  222.         add     esp,4   ; ignore pushed EIP
  223.         stc
  224.         Pop    Edi
  225.         Pop    Eax
  226.         ret
  227.  
  228. GetUltraConfig ENDP
  229.  
  230.  
  231.  
  232.  
  233.  
  234. comment %
  235. ╒══════════════════════════════════════════════════════════════════════════╕
  236. │    COMPLETELY RESET THE GRAVIS ULTRASOUND                                │
  237. │                                                                          │
  238. │                                                                          │
  239. │ INPUT:                                                                   │
  240. │       BL = GF1  IRQ number  ( IRQ must be 0,2,3,5,7,11,12 or 15 )        │
  241. │       BH = MIDI IRQ number                                               │
  242. │       CL = DMA Playback channel  ( DMA must be 0,1,3,5,6 or 7 )          │
  243. │       CH = DMA Record channel                                            │
  244. │       DX = Base port address of the Ultrasound ( must be 2x0h )          │
  245. │                                                                          │
  246. │                                                                          │
  247. │ OUTPUT:                                                                  │
  248. │    The function will fail if an illeagal DMA or IRQ number is selected   │
  249. │    and/or if the card has was not detected at the specified bass address │
  250. │                                                                          │
  251. │      If function successful the carry is cleared and                     │
  252. │       the card is fully reset and all 32 voices are initalised           │
  253. │       EDI = DRAM installed on the ultrasound                             │
  254. │                                                                          │
  255. │ Other registers of the GF1 are set as follows                            │
  256. │        LINE OUT enabled                                                  │
  257. │        MIC  IN  disabled                                                 │
  258. │        LINE IN  disabled                                                 │
  259. │                                                                          │
  260. │NOTES:                                                                    │
  261. │     o    This routine will probe the ultrasound on port address DX       │
  262. │     o    This function should only need to be used once by your program. │
  263. │     o    Both PICs ( 8259's ) mask registers might be modified.          │
  264. │     o    If the IRQ number is ZERO then the Ultrasound is programmed     │
  265. │          with that IRQ disabled.                                         │
  266. │     o    If the DMA channel is ZERO then the Ultrasound is programmed    │
  267. │          with that DMA disabled.                                         │
  268. │     o    EDI will contain the amount of RAM ( in bytes ) installed on the│
  269. │           Ultrasound however it dos not do a complete RAM test. It will  │
  270. │           always return 0KB, 256KB ,512KB, 768KB or 1024KB.              │
  271. │                                                                          │
  272. └───────────────────────────────────────────────────────────────────────── %
  273. Ultrasound_Reset PROC
  274.  
  275. local   dma_control     :BYTE
  276. local   irq_control     :BYTE
  277. local   gf1             :Byte
  278. local   midi            :Byte
  279. local   dram            :Byte
  280. local   adci            :Byte
  281. local   gus_dram_size   :Dword
  282.  
  283.  
  284.         pushad
  285.  
  286.         cmp     GUSdetected_flag, TRUE         ; Don't detect if a GUS has
  287.         je @@skip_detection                    ; already been detected.
  288.  
  289.  
  290.      ;
  291.      ; check if DX = 2x0h.  where x = 1,2,3,4,5,,,F
  292.      ;
  293.         mov     eax,edx
  294.         and     ax,0F0Fh
  295.         cmp     ax,0200h
  296.         jne  invalid_setting
  297.         mov     al,dl
  298.         and     al,0F0h
  299.         jz  invalid_setting
  300.  
  301.         call    Ultrasound_probe          ; See if there's an ultrasound
  302.         jc  invalid_setting
  303.  
  304.  
  305. @@skip_detection:
  306.  
  307.         and     bx,0f0fh
  308.         and     cx,0707h
  309.         mov     GF1,bl              ; Save IRQ's
  310.         mov     midi,bh
  311.  
  312.      ;****   convert IRQ numbers into register value   *****
  313.                 movzx   edx,bl
  314.                 and     dl,dl
  315.                 jz  Zero_irq1
  316.                 mov     dl,irq_reg_list[edx]
  317.                 and     dl,dl
  318.                 jz  invalid_setting
  319. Zero_irq1:      mov     irq_control,dl
  320.  
  321.                 movzx   edx,bh
  322.                 and     dl,dl
  323.                 jz  Zero_irq2
  324.                 mov     dl,irq_reg_list[edx]
  325.                 and     dl,dl
  326.                 jz  invalid_setting
  327.                 shl     dl,3
  328. Zero_irq2:      or      irq_control,dl
  329.  
  330.                 cmp     bh,bl                        ; Chech if both IRQ
  331.                 jne diff_irqs                        ;   are equal then
  332.                 and     bl,bl                       ;( Except when zero)
  333.                 jz  diff_irqs
  334.                 and     irq_control,0111b            ; Clear Channel 2 IRQ
  335.                 or      irq_control,40h              ; and turn on bit 6
  336. diff_irqs:
  337.  
  338.      ;****   convert DMA number into register value   *****
  339.                 movzx   edx,cl
  340.                 and     dl,dl
  341.                 jz  Zero_dma2
  342.                 mov     dl,dma_reg_list[edx]
  343.                 and     dl,dl
  344.                 jz  invalid_setting
  345. Zero_dma1:      mov     dma_control,dl
  346.  
  347.                 movzx   edx,ch
  348.                 and     dl,dl
  349.                 jz  Zero_dma2
  350.                 mov     dl,dma_reg_list[edx]
  351.                 and     dl,dl
  352.                 jz  invalid_setting
  353.                 shl     dl,3
  354. Zero_dma2:      or      dma_control,dl
  355.  
  356.                 cmp     ch,cl                        ; Chech if both DMAs
  357.                 jne diff_dmas                        ;   are equal then
  358.                 and     cl,cl                       ;( Except when zero)
  359.                 jz  diff_irqs
  360.                 and     dma_control,0111b            ; Clear Channel 2 DMA
  361.                 or      dma_control,40h              ; and turn on bit 6.
  362. diff_dmas:
  363.  
  364.  
  365.  
  366.         cli                         ; must not be disterbed
  367.  
  368. ; The code below sets the DMA and IRQ  settings of the Ultrasound
  369. ;  It was sort of taken from the file RESET.C  of GUS SDK  V2.10
  370.  
  371.         mov     ecx,200h            ; delay a bit
  372.         loop $
  373.  
  374.  
  375. ;/* Set up for Digital ASIC */
  376.         mov    dx,GUS_base_port
  377.         add     dx,0fh
  378.         mov     al,5
  379.         out     dx,al           ; Seems to be a undocumented register
  380.  
  381.         outp    mix_control,00001011b
  382.         outp    IRQDMA_Ctrl,0
  383.  
  384.         mov     dx,GUS_base_port
  385.         add     dx,0fh
  386.         mov     al,0
  387.         out     dx,al
  388.  
  389. ;/* First do DMA control register */
  390.     outp        mix_control,00001011b
  391.     mov         dx,IRQDMA_Ctrl
  392.     mov         al,dma_control
  393.     or          al,80h
  394.     out         dx,al
  395.  
  396. ;/* IRQ CONTROL REG */
  397.     outp        mix_control,01001011b
  398.     outp        IRQDMA_Ctrl,irq_control
  399.  
  400. ;/* First do DMA control register */
  401.     outp        mix_control,00001011b
  402.     outp        IRQDMA_Ctrl,dma_control
  403.  
  404. ;/* IRQ CONTROL REG */
  405.     outp        mix_control,01001011b
  406.     outp        IRQDMA_Ctrl,irq_control
  407.  
  408. ;/* IRQ CONTROL, ENABLE IRQ */
  409. ;/* just to Lock out writes to irq\dma register ... */
  410.         outp    GF1_Voice_Select,0
  411.  
  412. ;/* enable output & irq, disable line & mic input */
  413.     outp        mix_control,0001001b
  414.  
  415. ;/* outp just to Lock out writes to irq\dma register ... */
  416.         outp    GF1_Voice_Select,0
  417.  
  418.  
  419.  
  420. ;
  421. ; Unmask the IRQ lines  for the GF1 and MIDI IRQ settings
  422. ;
  423.  ; NOTE: the pin labled IRQ 2 on the BUS connects to IRQ 9 of the PIC
  424.  ; controllers. The IRQ 2 on the PIC is used for slave.
  425.  ; The ultrasound SDK ( Software Development Kit ) says that the GUS can use
  426.  ; IRQ 2 this means you must actualy hook IRQ 9.
  427.  
  428.         in      al,0A1h
  429.         mov     ah,al
  430.         in      al,21h
  431.         mov     cl,GF1                 ; Get GF1 IRQ
  432.         cmp cl , 2                     ; gota put right IRQ 2
  433.         jne j3
  434.            mov cl,9
  435.     j3:
  436.         mov     ebx,1
  437.         shl     ebx,cl
  438.         not     ebx
  439.         and     eax,ebx
  440.         mov     cl,MIDI                ; Get MIDI IRQ
  441.         cmp cl , 2                     ; gota put right IRQ 2
  442.         jne j4
  443.            mov cl,9
  444.     j4:
  445.         mov     ebx,1
  446.         shl     ebx,cl
  447.         not     ebx
  448.         and     eax,ebx
  449.         out     021h,al
  450.         mov     al,ah
  451.         out     0A1h,al
  452.         sti
  453.  
  454.  
  455.    ;
  456.    ;   Get amount of RAM installed on the sound card (return into EDI)
  457.    ;
  458.         xor     edi,edi
  459. GetSizeloop:
  460.         mov     ecx,edi                           ; Set DRAM  I/O address
  461.         call    UltraSetDRAM_address
  462.         in      al,dx                           ; see if the DRAM locaion
  463.         mov     cl,al                           ; can store some data
  464.         not     al
  465.         out     dx,al
  466.         in      al,dx
  467.         cmp     al,cl
  468.         jz   NoDRAM
  469.         add     edi,40000h
  470.         cmp     edi,100000h                     ; the GF1 can only hold 1MB
  471.         jb  GetSizeloop
  472.  
  473. NoDRAM: add     edi,3ffffh                      ; align EDI on 256KB
  474.         and     edi,NOT 3ffffh
  475.         mov     gus_dram_size,edi
  476.  
  477.  
  478. ;*** Initalise the UltraSound  ****
  479.         call Ultrasound_Init
  480.  
  481.         clc
  482.         popad
  483.         mov     edi,gus_dram_size
  484.         ret
  485.  
  486.  
  487. invalid_setting:                            ; jump here on error
  488.          stc
  489.          popad
  490.          ret
  491.  
  492. ;=================== Ultrasound reseted ============================
  493. Ultrasound_Reset ENDP
  494.  
  495.  
  496. comment %
  497. ╒══════════════════════════════════════════════════════════════════════════╕
  498. │           INITALIZE  THE  ULTRASOUND'S  VOICES                           │
  499. │                                                                          │
  500. │                                                                          │
  501. │                                                                          │
  502. │   IN:  nothing                                                           │
  503. │                                                                          │
  504. │  OUT:   All 32 voices have initalized , cleared buffered IRQ's           │
  505. │        enables line out                                                  │
  506. │  Each of the 32 voices are set as follows                                │
  507. │                                                                          │
  508. │Frequency     = 0                                                         │
  509. │Voice stoped                                                              │
  510. │Bi-directional looping off                                                │
  511. │IRQs disabled                                                             │
  512. │Current Volume = 0                                                        │
  513. │Active Number of Voices = 14                                              │
  514. │                                                                          │
  515. │NOTE:                                                                     │
  516. │     o    This function will only be successful on a successful call      │
  517. │          to the "Ultrasound_Reset" routine                               │
  518. └──────────────────────────────────────────────────────────────────────────┘%
  519. Ultrasound_Init PROC
  520.  
  521.          cmp     GUSdetected_flag, TRUE         ; do only if gus has
  522.          je GUSok                               ; been previously detected
  523.          stc
  524.          ret
  525.  
  526. GUSok:
  527.         pushad
  528.  
  529. ;/* Pull a reset on the GF1 */
  530.         mov     al,04Ch
  531.         mov     cl,00000000b
  532.         call    Set_GF1_ByteRegister
  533.  
  534. ;/* Wait a little while ... */
  535.         mov     ecx,10
  536. J56:     call   GF1_delay
  537.         loop J56
  538.  
  539. ;/* Release Reset */
  540.        mov     al,04Ch
  541.         mov     cl,00000001b
  542.         call    Set_GF1_ByteRegister
  543.  
  544. ;/* Wait a little while ... */
  545.         mov     ecx,10
  546. J57:    call   GF1_delay
  547.        loop J57
  548.  
  549. ;/* Reset the MIDI port also */
  550.         mov     edx,dword ptr midi_control
  551.         mov     al,00000011b
  552.         out     dx,al
  553.  
  554.         mov     ecx,10
  555. J58:    call   GF1_delay
  556.         loop J58
  557.  
  558.         xor     al,al
  559.         out     dx,al
  560.  
  561. ;/* Clear all interrupts. */
  562.         mov     al,41h                  ;DRAM  DMA Control Register
  563.         mov     cl,0
  564.         call    Set_GF1_ByteRegister
  565.         mov     al,045h                   ;Timer  Control Register
  566.         mov     cl,00h
  567.         call    Set_GF1_ByteRegister
  568.         mov     al,049h                   ;Sampling  Control Register
  569.         mov     cl,00h
  570.         call    Set_GF1_ByteRegister
  571.  
  572.         mov     al,0Eh              ; set active voices to 32
  573.         mov     cl, 31 or 0C0h
  574.         call    Set_GF1_ByteRegister
  575.  
  576.  
  577. ;/* Clear interrupts on voices. */
  578. ;/* Reading the status ports will clear the irqs. */
  579.         mov     edx,dword ptr GF1_IRQ_status      ; Read
  580.         in      al,dx
  581.         mov     al,041h                       ;DRAM  DMA Control Register
  582.         call    read_GF1_ByteRegister
  583.         mov    al,049h                 ; Sampling  Control Register
  584.         call    read_GF1_ByteRegister
  585. ClrFIFO:mov     al,08Fh                 ;IRQ source Register
  586.         call    read_GF1_ByteRegister
  587.         and     al,11000000b
  588.         cmp     al,11000000b            ; keep on reading to clear IRQ's
  589.         jne ClrFIFO
  590.  
  591.  
  592.          mov    BL,0
  593.     stop_loop:
  594.                 outp    GF1_Voice_Select,BL  ; select voice to operate with
  595.                 mov     al,00h                   ; set Voice control
  596.                 mov     cl,00000010b               ; (Stoped voice )
  597.                 call    Set_GF1_ByteRegister
  598.                 mov     al,0Dh                 ; set Volume Ramp control
  599.                 mov     cl,00000010b                ; ( stoped ramping)
  600.             call    Set_GF1_ByteRegister
  601.                 mov     al,09h                   ; Current Volume fully off
  602.             xor     ecx,ecx
  603.             call    Set_GF1_WordRegister
  604.                 call   GF1_delay        ; /* Wait 4.8 micos. or more. */
  605.  
  606.         inc    bl
  607.         cmp    bl,32
  608.         jb stop_loop
  609.  
  610.  
  611.         mov     edx,dword ptr GF1_IRQ_status      ; Read
  612.         in      al,dx
  613.         mov     al,041h                  ;DRAM  DMA Control Register
  614.         call    read_GF1_ByteRegister
  615.         mov    al,049h                 ; Sampling  Control Register
  616.         call    read_GF1_ByteRegister
  617. Cl2FIFO:mov     al,08Fh                 ;IRQ source Register
  618.         call    read_GF1_ByteRegister
  619.         and     al,11000000b
  620.         cmp     al,11000000b            ; keep on reading to clear IRQ's
  621.         jne Cl2FIFO
  622.  
  623.         mov     al,0Eh              ; set active voices to 14 again
  624.         mov     cl, 13 or 0C0h
  625.         call    Set_GF1_ByteRegister
  626.  
  627.  
  628.         ;/* Set up GF1 Chip for interrupts & enable DACs. */
  629.         mov     al,04Ch
  630.         mov     cl,00000111b
  631.         call    Set_GF1_ByteRegister
  632.  
  633.         clc
  634.         popad
  635.         ret
  636. Ultrasound_Init ENDP
  637.  
  638.  
  639.  
  640.  
  641. ;--------------------- end of ultrasound services ----------------------
  642.  
  643.  
  644.  
  645. ; Some little procedures that are used by the Ultrasound services
  646. read_GF1_ByteRegister proc
  647.         mov     edx,dword ptr GF1_Reg_Select
  648.         out     dx,al
  649.         add     dl,2
  650.         in      al,dx
  651.         ret
  652. read_GF1_ByteRegister endp
  653.  
  654. Set_GF1_ByteRegister proc
  655.         mov     edx,dword ptr GF1_Reg_Select
  656.         out     dx,al
  657.         add     dl,2
  658.         mov     al,cl
  659.         out     dx,al
  660.         ret
  661. Set_GF1_ByteRegister endp
  662.  
  663. Set_GF1_WordRegister proc
  664.         mov     edx,dword ptr GF1_Reg_Select
  665.         out     dx,al
  666.         inc     dl
  667.         mov     eax,ecx
  668.         out     dx,ax
  669.         ret
  670. Set_GF1_WordRegister endp
  671.  
  672.  
  673.  
  674. ;/***************************************************************
  675. ; * This function is used as a 1.6*3 microsecond (or longer) delay.
  676. ; * This is needed when trying to change any of the 'self-modifying
  677. ; * bits in the voice registers.
  678. ; ***************************************************************/
  679. GF1_delay        PROC 
  680.         push    edx
  681.         mov     ah,7h
  682. J55:     mov     dx,GF1_DRAM        ; dummy port Read
  683.         in      al,dx
  684.         dec     ah
  685.         jnz  J55
  686.         pop     edx
  687.         ret
  688. GF1_delay ENDP
  689.  
  690. ;============================================================================
  691. ;
  692. ; Probe for an Ultrasound
  693. ;
  694. ; Expects      DX  = Ultrasound base port address
  695. ;
  696. ; Returns      Carry clear if detected a GUS at this port address
  697. ;               otherwise carry is set.
  698. ;
  699. ;============================================================================
  700. Ultrasound_Probe PROC
  701.   push    Eax
  702.   push    Edx
  703.   push    Ecx
  704.  
  705.   cmp     GUSdetected_flag, TRUE         ; Don't detect if a GUS has aleady
  706.   je skip_detection                      ; been detected because some how
  707.                                          ; I don't think too many pople are
  708.                                          ; going to be unpluging thier GUS
  709.                                          ; half way through a game.
  710.  
  711.         mov     GUS_Base_Port,DX
  712.                                  ; Take the Ultrasound out of a reset state
  713.         add     dx,103h          ; because it's in a reset state at power up.
  714.         mov     al,04Ch
  715.         out     dx,al
  716.         add     dl,2
  717.         mov     al,00000111b
  718.         out     dx,al
  719.         mov     ecx,100h              ; delay a bit ????
  720.         loop $
  721.  
  722.  
  723.         xor      ecx,ecx                        ; Set location 0 to 055h
  724.         call    UltraSetDRAM_address
  725.         mov     al,055h
  726.         out     dx,al
  727.  
  728.         inc     ecx                             ; Set location 1 to 0AAh
  729.         call    UltraSetDRAM_address
  730.         mov     al,0AAh
  731.         out     dx,al
  732.  
  733.         xor      ecx,ecx                        ; Read  location 0 and
  734.         call     UltraSetDRAM_address           ; compare it to 055h.
  735.         in       al,dx
  736.         cmp      al,055h
  737.         jne No_GUS_Found_here
  738.         mov     GUSdetected_flag,True         ; Set the GUS detected flag
  739.    ;
  740.    ; OK, there is a GUS. Time to initalize the port address varibles.
  741.    ;
  742.               mov     ax,GUS_Base_Port
  743.             mov     ecx,offset The_Ultrasound_port_Addresses
  744. PAdrLoop:     add     [ecx],ax
  745.               add     ecx,2
  746.               cmp     ecx,offset Ultrasound_ports_ends
  747.               jb PAdrLoop
  748.  
  749. skip_detection:
  750.         clc
  751.         pop     ecx
  752.         pop     edx
  753.         pop     eax
  754.         ret
  755.  
  756. No_GUS_Found_here:
  757.         stc
  758.         pop     ecx
  759.         pop     edx
  760.         pop     eax
  761.         ret
  762.  
  763. Ultrasound_Probe ENDP
  764.  
  765. ;----------------------------------------------------------
  766. ; Procedure to set the DRAM I/O address of the Ultrasound
  767. ;
  768. ; Expects       ECX with address
  769. ;
  770. UltraSetDRAM_address PROC
  771.         mov     DX,GUS_Base_Port
  772.         add     dx,103h
  773.         mov     al,043h                 ; DRAM I/O reg  bits 0..15
  774.         out     dx,al
  775.         inc     dl
  776.         mov     eax,ecx
  777.         out     dx,ax
  778.         dec     dl
  779.         mov     al,044h                 ; DRAM I/O reg bits 16..19
  780.         out     dx,al
  781.         add     dl,2
  782.         shr     eax,16
  783.         out     dx,al
  784.         add     dl,2                    ; set DX to  DRAM port
  785.         ret
  786. UltraSetDRAM_address ENDP
  787.  
  788.  
  789.  
  790. ;********************* END OF THE ULTRASOUND ROUTINES *********************
  791. END
  792.