data segment c equ 523 ;Frequenzen der T”ne d equ 587 e equ 659 f equ 698 g equ 784 a equ 880 h equ 988 Song: dw c,250, d,250, e,250, f,250, g,500, g,500 dw a,250, a,250, a,250, a,250, g,500 dw a,250, a,250, a,250, a,250, g,500 dw f,250, f,250, f,250, f,250, e,500, e,500 dw d,250, d,250, d,250, d,250, c,500 dw 0 ;Abschluá immer mit 0 oldInt dd 0 ;Zeiger auf alten Handler Zaehler dw 0 ;Zaehler, wird einmal pro ms dekrem. data ends code segment assume cs:code,ds:data handler proc far ;neuer IRQ 0 - Handler pushf call dword ptr oldint ;alten Handler aufrufen mov ax,data ;Datensegment Zugriff erm”glichen mov ds,ax dec word ptr Zaehler ;Zaehler dekrementieren iret handler endp prepare proc near ;bereitet Timer und Speaker vor mov dx,61h ;Controll-Port laden in al,dx or al,3 ;untere Bits setzen (enable Speaker) out dx,al mov al,36h ;Schreibzugriff Timer 0 mov cx,04a9h ;Interrupt-Abstand 1 ms out 43h,al ;Befehl senden mov al,cl out 40h,al ;Timer-Wert senden mov al,ch out 40h,al mov ax,3508h ;alten Interrupt-Vektor lesen int 21h mov word ptr oldint,bx ;Vektor sichern mov word ptr oldint+2,es push ds mov ax,cs ;Vektor auf Handler in ds:dx mov ds,ax lea dx,handler mov ax,2508h ;und neuen Vektor setzen int 21h pop ds ret prepare endp close proc near ;setzt Timer und Speaker wieder zurck push ds lds dx,oldint ;alten Vektor restaurieren mov ax,2508h int 21h mov al,36h ;Timer zurcksetzen out 43h,al xor al,al out 40h,al ;auf 18,2 Interrupts pro Sekunde out 40h,al mov dx,61h ;Speaker aus in al,dx and al,not 3 ;(Speaker enable l”schen) out dx,al pop ds ret close endp delay proc near ;wartet (Zeit in ms in ax) mov zaehler,ax ;Zaehler laden warte: cmp zaehler,0 ;warten, bis Interrupt jne warte ;Zaehler auf 0 gez„hlt hat ret delay endp sound proc near mov bx,ax ;Frequenz nach bx mov al,0b6h ;Timer 2 auf Rechteck programmieren out 43h,al mov dx,0012h ;1.193 MHz Eingangsfrequenz mov ax,34ddh div bx ;Timer-Wert berechnen out 42h,al ;Low-Byte an Timer 2 mov al,ah out 42h,al ;High-Byte an Timer 2 ret sound endp start proc mov ax,data ;Zugriff auf Datensegment erm”glichen mov ds,ax call prepare ;Timer und Speaker initialisieren lea si,song ;Zeiger auf Frequenzen weiter: lodsw ;Frequenz holen or ax,ax je fertig ;Abschluá-Byte gefunden ? call sound ;Sound ausgeben lodsw ;Dauer laden call delay ;und warten jmp weiter fertig: call close ;Timer und Interrupts zurcksetzen mov ah,4ch ;Programm beenden int 21h start endp code ends end start