Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- kod segment
- assume cs:kod,ss:stosik,ds:dane
- start:
- mov ax,dane
- mov ds,ax
- mov ax,stosik
- mov ss,ax
- mov sp,offset szczyt
- ;czyszczenie ekranu
- mov ah,0
- mov al,03h
- int 10h
- mov ah,62h ;wywolanie przerwania ktore wrzuca do bx offset prefiksu PSP
- int 21h
- mov es,bx
- mov al,es:[0080h] ;przekazanie ilosci znakow parametru do AL
- mov cl,al
- mov si,0 ;ustawiamy SI na 0, zeby czytac od poczatku parametru
- dec cl ;dwa ostatnie znaki parametru to znak 10 i 13 w ascii, czyli enter, musimy sie ich pozbyc
- dec cl
- cmp al,2 ;jesli parametr ma 2 lub mniej znakow, wtedy wyswietlamy komunikat o braku parametru
- jbe brakParametru
- przepisywanie:
- mov al,es:[0081h+si+1] ;przekazanie znakow z bufora do al. Zaczynamy od 82, bo 81 to spacja po nazwie pliku
- lea bx,nazwa ;offset zmiennej 'nazwa' do bx
- mov ds:[bx+si],al ;przekazanie znaku do zmiennej lancuchowej
- cmp cl,0; porownanie rejestru CL z 0
- je end_przepisywanie; jesli CL=0 to skocz do zakoncz przepisywanie
- dec cl; zmniejsz wartosc CL o jeden
- inc si; zwieksz SI o 1
- jmp przepisywanie;
- brakParametru:
- lea dx,napis1;
- call naekran;
- jmp kbhit;
- end_przepisywanie:
- mov al,03h ;czyszczenie ekranu
- int 10h
- call otworz_plik;
- lea dx,napis
- call naekran;
- melodia:
- call czytaj_z_pliku
- lea bx,bufor ;przeniesienie offsetu 3 znakowego bufora do BX
- mov dl,ds:[bx+0] ;znak pierwszy odpowiada za nute
- cmp dl,'W' ;jesli nuta jest 'W' oznacza to koniec melodii i konczy program
- je exit ;skok do zakonczenia programu
- ; Przerwanie melodii po wcisnieciu dowolnego klawisza
- mov ah,0Bh
- int 21h ;przerwanie, ktore sprawdza, czy zostal wcisniety jakis klawisz i przechowuje ta informacje w AL
- cmp al,0 ;jesli AL nie jest puste, oznacza to, ze zostal wcisniety jakis klawisz
- jne exit; ;warunkowy skok do zakonczenia programu
- jmp nuty ;w przeciwnym wypadku przechodzi do odegrania nuty
- exit:
- call zamknij_plik;
- mov ah,4ch
- mov al,00h
- int 21h ;wywolanie przerwania konczacego program
- nuty: cmp dl,'C'
- je dojump
- cmp dl,'D'
- je rejump
- cmp dl,'E'
- je mijump
- cmp dl,'F'
- je fajump
- cmp dl,'G'
- je sojump
- cmp dl,'A'
- je lajump
- cmp dl,'H'
- je zijump
- cmp dl,'c'
- je cisjump
- cmp dl,'d'
- je disjump
- cmp dl,'f'
- je fisjump
- cmp dl,'g'
- je gisjump
- cmp dl,'a'
- je aisjump
- mov ton,1
- jmp graj
- dojump:jmp do ;Wszystkie ponizsze skoki sa tylko po to, bo skoki maja okreslony dystans, a te powyzsze sa za dalekie i sie nie kompiluje
- aisjump:jmp ais
- gisjump:jmp gis
- fisjump:jmp fis
- disjump:jmp dis
- cisjump:jmp cis
- zijump:jmp zi
- lajump:jmp la
- sojump:jmp so
- fajump:jmp fa
- mijump:jmp mi
- rejump:jmp re
- ;odczytanie drugiego znaku - oktawy
- graj: lea bx,bufor
- mov cl,ds:[bx+1] ;znak drugi odpowiada za oktawe
- sub cl,30h ;konwersja ze znaku ascii na liczbe
- shr ton,cl ;zmniejszamy ton, czyli dzielnik czestotliwosci. Zmniejszajac dzielnik, zwiekszamy wynik.
- ;odczytanie trzeciego znaku - czasu trwania dzwieku/pauzy
- lea bx,bufor
- mov cl,ds:[bx+2] ;znak trzeci odpowiada za czas
- sub cl,30h ;konwersja z ascii na liczbe
- mov ch,0 ;czas moze byc liczba od 0 do 9, wiec rejestr CH powinien byc pusty. Zerujemy go, zeby miec pewnosc
- mov czas,cl ;przenosimy informacje o czasie z rejestru CX do zmiennej
- call play;
- jmp melodia;
- do: mov ax,TC ;nie mozna przenosic bezposrednio z jednej zmiennej do drugiej, wiec wspomagamy sie rejestrem
- mov ton,ax
- jmp graj
- re: mov ax,TD
- mov ton,ax
- jmp graj
- mi: mov ax,TE
- mov ton,ax
- jmp graj
- fa: mov ax,TF
- mov ton,ax
- jmp graj
- so: mov ax,TG
- mov ton,ax
- jmp graj
- la: mov ax,TA
- mov ton,ax
- jmp graj
- zi: mov ax,TH
- mov ton,ax
- jmp graj
- cis: mov ax,TCis
- mov ton,ax
- jmp graj
- dis: mov ax,TDis
- mov ton,ax
- jmp graj
- fis: mov ax,TFis
- mov ton,ax
- jmp graj
- gis: mov ax,TGis
- mov ton,ax
- jmp graj
- ais: mov ax,TAis
- mov ton,ax
- jmp graj
- naekran:
- mov ah,09h;Funkcja wypisująca na ekran napis o adresie zawartym w rejestrze DX
- int 21h;Wywołanie przerwania DOSa z funkcją 09H
- ret;Powrót z procedury
- brak_pliku:
- lea dx,napis2 ;przeniesienie offsetu napisu do rejestru DX
- call naekran ;wyswietlenie napisu
- kbhit: mov ah,0Bh ; Ta czesc programu zatrzymuje go zaraz po jego zakonczeniu, abys my mogli zobaczyc to, co wyswietlil na ekranie. Bedzie sie zapetlac, dopoki nie nacisniemy jakiegos przycisku
- int 21h ;funkcja sprawdzająca czy jakikolwiek klawisz został naciśnięty
- cmp al,0 ;jezeli jakis przycisk zostal nacisniety, to w AL bedzie wartosc rozna od 0
- je kbhit ;jeżeli wynik jest zerem to powróć do etykiety KBHIT
- jmp exit ;jeżeli klawisz został naciśnięty to skocz bezwarunkowo do zakonczenia programu
- otworz_plik:
- mov ah,3dh ;funkcja przerwania 21H otwierajaca plik
- mov al,0 ;otwarcie tylko do czytania
- mov dx,offset nazwa ;nazwa pliku ktory ma byc otwarty
- int 21h
- jc brak_pliku ;jeżeli przerwanie zwróciło błąd to skocz do procedury brak_pliku
- mov uchwytPliku,ax ;zapisanie uchwytu pliku do zmiennej uchwytPliku
- ret
- zamknij_plik:
- mov ah,3Eh ;funkcja przerwania 21H zamykajaca plik
- mov bx,uchwytPliku ;uchwyt pliku, ktory ma zostac zamkniety
- int 21h
- ret
- czytaj_z_pliku:
- push cx
- push dx
- mov ah,3Fh ;funkcja przerwania 21H czytajaca z pliku
- mov bx,uchwytPliku ;uchwyt pliku, ktory ma byc otwarty
- mov cx,3 ;liczba bajtow do przeczytania. 3, bo kazdy dzwiek sklada sie z 3 znakow
- lea dx,bufor
- int 21h
- pop dx
- pop cx
- ret
- sound:
- mov ax,ton
- mov dx,42h
- out dx,al ;wysylanie zawartosci AL do portu 42h, ktory odpowiada za glosnik. Innymi slowy - generowanie dzwieku
- mov al,ah
- out dx,al ; tutaj i wyzej mamy do czynienia z ukladem 8253
- ;zalaczenie glosnika
- mov dx,61h
- in al,dx ; pobranie zawartosci portu 61h do rejestru AL
- or al,00000011B ; maska or (ustawienie najmlodszych bitow na 1);
- out dx,al ; wysłanie zawartości rejestru AL do portu DX
- ret ; w powyzszych rozkazach mamy do czynienia z ukladem 8255
- ;Wylaczenie glosnika
- nosound:
- mov dx,61h
- in al,dx ;pobranie zawartosci portu 61h do rejestru AL
- and al,11111100B ;maska and (ustawienie najmlodszych bitow na 0);
- out dx,al;
- ret
- play:
- call sound ;wlaczenie glosnika
- push cx
- push dx
- mov cl,czas ;ustawianie wiekszej czesci czasu na czas trwania dzwieku
- mov dx,0 ;ustawianie mniejszej czesci czasu na 0
- mov ah,86h ;funkcja ktora nic nie robi przez CX:DX mikrosekund
- int 15h
- call nosound ;wylaczenie glosnika
- pop dx
- pop cx
- ret
- kod ends;
- dane segment
- ton dw 0
- czas db 0
- uchwytPliku dw 0
- ;plik
- bufor db 3 dup(0)
- nazwa db 0,0,0,0,0,0,0,0,0,0,0,0,0; Nazwa pliku zakonczona #0
- NAPIS DB '* MUZYKA Z PLIKU *$';
- napis1 DB 'Podaj nazwe pliku w parametrze! ',10,13,'$' ;
- Napis2 db ' Plik nie istnieje !!!$';
- TC dw 36061; 1.19MHz/33Hz
- TD dw 32162; 1.19MHz/37Hz
- TE dw 29024; 1.19MHz/41Hz
- TF dw 27045; 1.19MHz/44Hz
- TG dw 24286; 1.19MHz/49Hz
- TA dw 21636; 1.19MHz/55Hz
- TH dw 19194; 1.19MHz/62Hz
- TCis dw 34000; 1.19Mhz/35Hz
- TDis dw 30512; 1.19Mhz/39Hz
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement