home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / UTILITIE / VOCSHO.ZIP / PC_SOUND.ASM < prev    next >
Assembly Source File  |  1991-01-07  |  6KB  |  208 lines

  1. package assembly pc_sound is
  2.  
  3. if memory_model = 0 then
  4.   pragma memory_model(0);
  5. else
  6.   pragma memory_model(1);
  7. end if;
  8.  
  9. CSEG
  10.         jmp     main                    -- jump to initialization
  11.  
  12. DSEG
  13. prevwhistle db ?
  14. a_sample_duration dw ?
  15. on_off_bytes db 256 dup(?)
  16.  
  17. CSEG
  18. on_off_pattern equ  $
  19.  dw 2#00000000_11111111#       -- 0    nibbles are in sign+magnitude form
  20.  dw 2#00000001_11111111#       -- 1
  21.  dw 2#00000011_11111111#       -- 2
  22.  dw 2#00000111_11111111#       -- 3
  23.  dw 2#00001111_11111111#       -- 4
  24.  dw 2#00011111_11111111#       -- 5
  25.  dw 2#00111111_11111111#       -- 6
  26.  dw 2#01111111_11111111#       -- 7
  27.  dw 2#00000000_11111110#       -- -1
  28.  dw 2#00000000_01111110#       -- -2
  29.  dw 2#00000000_00111110#       -- -3
  30.  dw 2#00000000_00011110#       -- -4
  31.  dw 2#00000000_00001110#       -- -5
  32.  dw 2#00000000_00000110#       -- -6
  33.  dw 2#00000000_00000010#       -- -7
  34.  dw 2#00000000_00000000#       -- -8
  35.  
  36. get_ticks:             -- return current tick count in ax
  37.        xor al,al
  38.        pushf           --  save int enable status
  39.        cli             --  lock out interrupts
  40.        out 43h,al      --  read counter 0
  41.        jmp short gtl   --    (don't go too fast)
  42. gtl:
  43.        in al,40h       --  get lsb of timer
  44.        xchg ah,al      --
  45.        jmp short gth   --    (don't go too fast)
  46. gth:
  47.        in al,40h       --  get msb of timer
  48.        xchg ah,al      --
  49.        popf            --  restore int enable status
  50.        ret
  51.  
  52. play_ax_till_dx:       -- destroys ax,bx
  53.                        -- high nibble of al contains amplitude
  54.                        -- dx contains timeout value
  55.        mov bx,on_off_bytes
  56.        add bx,ax
  57.        xchg si,bx
  58.        even
  59. pbd_loop:              -- output 16 speaker on/off bytes, then,
  60.        push dx         -- if we haven't timed out, do it again
  61.        mov dx,61h
  62.        lodsw
  63.        out dx,al
  64.        mov al,ah
  65.        out dx,al
  66.        lodsw
  67.        out dx,al
  68.        mov al,ah
  69.        out dx,al
  70.        lodsw
  71.        out dx,al
  72.        mov al,ah
  73.        out dx,al
  74.        lodsw
  75.        out dx,al
  76.        mov al,ah
  77.        out dx,al
  78.        lodsw
  79.        out dx,al
  80.        mov al,ah
  81.        out dx,al
  82.        lodsw
  83.        out dx,al
  84.        mov al,ah
  85.        out dx,al
  86.        lodsw
  87.        out dx,al
  88.        mov al,ah
  89.        out dx,al
  90.        lodsw
  91.        out dx,al
  92.        xor al,al
  93.        pushf           --  save int enable status
  94.        cli             --  lock out interrupts
  95.        out 43h,al      --  read counter 0
  96.        mov al,ah
  97.        out dx,al
  98.        in al,40h       --  get lsb of timer
  99.        xchg ah,al      --
  100.        sub si,16
  101.        in al,40h       --  get msb of timer
  102.        xchg ah,al      --
  103.        popf            --  restore int enable status
  104.        pop dx
  105.        cmp ax,dx
  106.        jns pbd_loop
  107.        xchg si,bx
  108.        ret
  109.  
  110. play_it_out:
  111.                        -- ds:si => sound block
  112.                        -- cx    => N of bytes in sound block
  113.                        -- destroys ax,bx,dx and si,cx
  114.        call get_ticks
  115.        mov dx,ax
  116.        cld
  117. play_it_out_loop:
  118.        mov al,es:[si]
  119.        and ax,16#00F0#;
  120.        sub dx,[a_sample_duration]
  121.        call play_ax_till_dx
  122.        mov al,es:[si]
  123.        inc si
  124.        and ax,16#000F#
  125.        shl al,1
  126.        shl al,1
  127.        shl al,1
  128.        shl al,1
  129.        sub dx,[a_sample_duration]
  130.        call play_ax_till_dx
  131.        loop play_it_out_loop
  132.        mov al,[prevwhistle]
  133.        out 61h,al
  134.        ret
  135.  
  136. procedure set_sample_rate(samples_per_second:in sample_rates) is
  137.        pop ax          -- save ret address
  138.        if memory_model = 1 then
  139.          pop dx
  140.        end if;
  141.        pop cx          -- cx:=sound_length
  142.        if memory_model = 1 then  -- restore ret address
  143.          push dx
  144.        end if;
  145.        push ax
  146.        mov ax,13532    -- dx:ax := 1193180
  147.        mov dx,18
  148.        div cx
  149.        mov [a_sample_duration],ax
  150.        if memory_model = 0 then
  151.          ret
  152.        else
  153.          ret far
  154.        end if;
  155. end set_sample_rate;
  156.  
  157. procedure playback(sound:in system.address;sound_length:in natural) is
  158.                        -- clobbers ax,bx,cx,dx,si
  159.        pop ax          -- save ret address
  160.        if memory_model = 1 then
  161.          pop dx
  162.        end if;
  163.        pop cx          -- cx:=sound_length
  164.        pop si          -- si:=sound(sound'first)'address
  165.        mov bx,es
  166.        les si,lword ptr[si]
  167.        if memory_model = 1 then  -- restore ret address
  168.          push dx
  169.        end if;
  170.        push ax
  171.        push bx
  172.        call play_it_out
  173.        pop  es
  174.        if memory_model = 0 then
  175.          ret
  176.        else
  177.          ret far
  178.        end if;
  179. end playback;
  180.  
  181. main:
  182.        mov ax,149      -- default sample rate:=8K
  183.        mov [a_sample_duration],ax
  184.        in al,61h
  185.        mov [prevwhistle],al
  186.        and al,16#FD#
  187.        mov bl,al               -- fill on_off_bytes with 16 lists of 16
  188.        mov di,on_off_bytes     -- speaker control bytes, on and off matching
  189.        mov cx,16               -- the bits in on_off_pattern
  190.        cld
  191.        mov si,on_off_pattern
  192. amplitude_loop:
  193.        push cx
  194.        seg cs
  195.        lodsw
  196.        mov cx,16
  197. bit_loop:
  198.        mov bh,2        --      bh:=non_speaker_bits | one bit from ax
  199.        and bh,al
  200.        or  bh,bl
  201.        mov [di],bh
  202.        inc di
  203.        ror ax,1
  204.        loop bit_loop
  205.        pop cx
  206.        loop amplitude_loop
  207. end pc_sound;
  208.