public  _low_init, _low_uninit, _low_set_bps, _low_set_rate, _low_set_voices
public  _low_get_freq, _low_put_data, _low_get_data, _low_mix, _low_rout
public	_low_vccmnd, _low_vccntrl, _low_vcsbeg, _low_vclbeg, _low_vclend
public	_low_vcfreq, _low_vcpan, _low_vcvol
public  _low_buf, _low_buflen, _low_bufptr, _low_ram, _low_rambase
public	_low_port, _low_irq, _low_dma

public  _sound_init

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
align 4
_low_init       dd      ?               ; ptr to init function
_low_uninit     dd      ?               ; ptr to uninit function
_low_set_bps    dd      ?               ; ptr to beats per second set function
_low_set_rate   dd      ?               ; ptr to mixing rate set function
_low_set_voices dd      ?               ; ptr to number of voices set function
_low_get_freq   dd      ?               ; ptr to frequency conversion function
_low_put_data   dd      ?               ; ptr to sample data put function
_low_get_data   dd      ?               ; ptr to sample data get function
_low_mix        dd      ?               ; ptr to mix ahead function

_low_rout       dd      _ret            ; ptr to routine to call on every beat

_low_vccmnd     db      16 dup(?)       ; virtual channel command bits       |
                                        ;  bit 0: volume change              |
                                        ;  bit 1: balance change             |
                                        ;  bit 2: frequency change           |
                                        ;  bit 3: sample note-on             |
                                        ;  bits 4-7: must be 0               |
_low_vccntrl    db      16 dup(?)       ; virtual channel voice control      |
                                        ;  bits 0-2: must be 0               |
                                        ;  bit 3: looping instrument         |
                                        ;  bits 4-7: must be 0               |
_low_vcsbeg     dd      16 dup(?)       ; virtual channel sample begin       |
_low_vclbeg     dd      16 dup(?)       ; virtual channel loop begin         |
_low_vclend     dd      16 dup(?)       ; virtual channel loop end           |
_low_vcfreq     dw      16 dup(?)       ; virtual channel frequency value    |
_low_vcpan      db      16 dup(?)       ; virtual channel pan position (0-15)|
_low_vcvol      db      16 dup(?)       ; virtual channel volume (0-0ffh)    |

_low_buf        dd      ?               ; length of buffer needed by driver
_low_buflen     dd      10000000h       ; really stupid length
_low_bufptr     dd      ?               ; ptr to buffer
_low_ram        dd      ?               ; amount of RAM for samples
_low_rambase    dd      ?               ; base of RAM ptr

_low_port       dw      ?               ; base port of sound card
_low_irq        db      ?               ; IRQ of sound card
_low_dma        db      ?               ; DMA channel of sound card

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Initialize sound driver
; In:
;   AL - beats per second (15-255)
;   AH - number of voices (1-16)
;   BX - mixing rate (8000-44100)
;   ESI -> soundcard data structure
; Notes:
;   _low_rout, _low_ram, _low_rambase, _low_port, _low_irq, _low_dma,
;    _low_bufptr, and _low_buflen must all be set before calling.
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
_sound_init:
        push eax ecx esi edi
        mov edi,offset _low_vccmnd
        xor ecx,ecx
        mov [edi],ecx
        mov [edi+4],ecx
        mov [edi+8],ecx
        mov [edi+12],ecx
        mov edi,offset _low_init
        mov ecx,9
        rep movsd
        call _low_init
        call _low_set_bps
        mov al,ah
        call _low_set_voices
        mov ax,bx
        call _low_set_rate
        pop edi esi ecx eax
        ret

