home *** CD-ROM | disk | FTP | other *** search
/ PC Underground / UNDERGROUND.ISO / speaker / play_frq.asm < prev    next >
Assembly Source File  |  1995-07-28  |  3KB  |  127 lines

  1. data segment
  2. c equ 523                       ;tone frequencies
  3. d equ 587
  4. e equ 659
  5. f equ 698
  6. g equ 784
  7. a equ 880
  8. h equ 988
  9.  
  10. Song:     dw c,250, d,250, e,250, f,250, g,500, g,500
  11.           dw a,250, a,250, a,250, a,250, g,500
  12.           dw a,250, a,250, a,250, a,250, g,500
  13.           dw f,250, f,250, f,250, f,250, e,500, e,500
  14.           dw d,250, d,250, d,250, d,250, c,500
  15.           dw 0                  ;always terminate with 0
  16.  
  17. oldInt     dd 0                 ;pointer to old handler
  18. counter   dw 0                  ;counter, decremented once per ms
  19. data ends
  20.  
  21. code segment
  22. assume cs:code,ds:data
  23.  
  24. handler proc far                ;new IRQ 0 handler
  25.   pushf
  26.   call dword ptr oldint         ;call old handler
  27.   mov ax,data                   ;enable data segment access
  28.   mov ds,ax
  29.   dec word ptr counter          ;decrement counter
  30.   iret
  31. handler endp
  32.  
  33. prepare proc near               ;prepares timer and speaker
  34.   mov dx,61h                    ;load control port
  35.   in al,dx
  36.   or al,3                       ;set lower bits (enable speaker)
  37.   out dx,al
  38.  
  39.   mov al,36h                    ;write access timer 0
  40.   mov cx,04a9h                  ;interrupt distance 1 ms
  41.   out 43h,al                    ;send command
  42.   mov al,cl
  43.   out 40h,al                    ;send timer value
  44.   mov al,ch
  45.   out 40h,al
  46.  
  47.   mov ax,3508h                  ;read old interrupt vector
  48.   int 21h
  49.   mov word ptr oldint,bx        ;store vector
  50.   mov word ptr oldint+2,es
  51.   push ds
  52.   mov ax,cs                     ;vector to handler in ds:dx
  53.   mov ds,ax
  54.   lea dx,handler
  55.   mov ax,2508h                  ;and set new vector
  56.   int 21h
  57.   pop ds
  58.   ret
  59. prepare endp
  60.  
  61. close proc near                 ;sets back timer and speaker
  62.   push ds
  63.   lds dx,oldint                 ;restore old vector
  64.   mov ax,2508h
  65.   int 21h
  66.  
  67.   mov al,36h                    ;reset timer
  68.   out 43h,al
  69.   xor al,al
  70.   out 40h,al                    ;to 18.2 interrupts per second
  71.   out 40h,al
  72.  
  73.   mov dx,61h                    ;speaker off
  74.   in al,dx
  75.   and al,not 3                  ;(clear speaker enable)
  76.   out dx,al
  77.   pop ds
  78.   ret
  79. close endp
  80.  
  81. delay proc near                 ;waits (time in ms in ax)
  82.   mov counter,ax                ;load counter
  83. wait1:
  84.   cmp counter,0                 ;wait until interrupt
  85.   jne wait1                     ;has counted counter to 0
  86.   ret
  87. delay endp
  88.  
  89. sound proc near
  90.   mov bx,ax                     ;frequency to bx
  91.   mov al,0b6h                   ;program timer 2 to rectangle
  92.   out 43h,al
  93.   mov dx,0012h                  ;1.193 MHz input frequency
  94.   mov ax,34ddh
  95.   div bx                        ;calculate timer value
  96.   out 42h,al                    ;low byte to timer 2
  97.   mov al,ah
  98.   out 42h,al                    ;high byte to timer 2
  99.   ret
  100. sound endp
  101.  
  102. start proc
  103.   mov ax,data                   ;enable access to data segment
  104.   mov ds,ax
  105.  
  106.   call prepare                  ;initialize timer and speaker
  107.  
  108.   lea si,song                   ;pointer to frequencies
  109.  
  110. continue:
  111.   lodsw                         ;get frequency
  112.   or ax,ax
  113.   je finished                   ;close byte found ?
  114.   call sound                    ;output sound
  115.   lodsw                         ;load duration
  116.   call delay                    ;and wait
  117.   jmp continue
  118.  
  119. finished:
  120.   call close                    ;reset timer and interrupts
  121.   mov ah,4ch                    ;end program
  122.   int 21h
  123. start  endp
  124.  
  125. code ends
  126. end start
  127.