Niezapominajki

Kartka świąteczna z pozytywką ;-)


Pewnie każdy pamięta (to taki żarcik), gdy pod koniec lat osiemdziesiątych coraz częściej zaczęły atakować nas wirusy komputerowe. Jednym z nich był wirus Vienna.

Zainspirowany grafiką ASCII pochodzącą z tego wirusa postanowiłem napisać program, który mógłby zostać wysłany do wszystkich użytkowników amatorskiej sieci Packet Radio jako życzenia świąteczne. To miała być taka kartka świąteczna z pozytywką.

Na melodię dla pozytywki wybrałem znaną powszechnie kolędę "Cicha noc". Wcześniej policzyłem częstotliwości dźwięków i wartości wpisywane do rejestru układu 8253, który m. in. sterował głośniczkiem w komputerach IBM PC XT/AT.




A oto treść programu w języku Turbo Assemblera:



  ;------------------------------------------------------------------
  ; Program napisany z okazji Swiat Bozego Narodzenia A.D. 1993
  ;
  ; Skompilowac Turbo_Assemblerem f-my Borland.
  ;
  ; Autor programu: Jacek Porembiński
  ;------------------------------------------------------------------

       MODEL TINY
       .CODE
       ORG 100H

  start:

          mov    ax,cs             ; Ustaw poprawna wartosc rejestru DS
          mov    ds,ax             ; (potrzebne tylko wtedy, gdy program
                                   ;  ma byc w postaci .EXE).

          mov    ax,07h            ; Ustaw tryb tekstowy - mono.
          int    10h               ;
                                   ; A teraz wyswietlimy obrazek na ekranie...
          mov    ah,09h            ; DO AH numer funkcji wyswietlania tekstu.
          mov    dx,offset PIC     ; Do DX adres poczatku bufora tekstu.
          int    21h               ; Wywolanie przerwania uslugowego DOS-u

  ;-------------------------------------
  ; Rozpoczecie grania koledy
  ; W DX wartosc licznika odpowiadajaca
  ; czestotliwosci odpowiedniej nuty
  ; do zagrania, w BX czas brzmienia.
  ;-------------------------------------
          mov    dx,0BE4h          ; G1
          mov    bx,09h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,03h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,12h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,09h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,03h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,12h
          call   PLAY

  ;---------------------------------------

          mov    dx,07F0h          ; D2
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,07F0h          ; D2
          mov    bx,06h
          call   PLAY
          mov    dx,0990h          ; H1
          mov    bx,12h
          call   PLAY
          mov    dx,08E8h          ; C2
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,08E8h          ; C2
          mov    bx,06h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,12h
          call   PLAY

  ;------------------------------------

          mov    dx,0A98h          ; A1
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,06h
          call   PLAY
          mov    dx,08E8h          ; C2
          mov    bx,09h
          call   PLAY
          mov    dx,0990h          ; H1
          mov    bx,03h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,06h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,09h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,03h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,06h
          call   PLAY

  ;------------------------------------

          mov    dx,0A98h          ; A1
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,06h
          call   PLAY
          mov    dx,08E8h          ; C2
          mov    bx,09h
          call   PLAY
          mov    dx,0990h          ; H1
          mov    bx,03h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,06h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,09h
          call   PLAY
          mov    dx,0A98h          ; A1
          mov    bx,03h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,06h
          call   PLAY

  ;-------------------------------------

          mov    dx,07F0h          ; D2
          mov    bx,0Bh
          call   PLAY
          mov    dx,10h            ;
          mov    bx,01h
          call   PLAY
          mov    dx,07F0h          ; D2
          mov    bx,06h
          call   PLAY
          mov    dx,06ACh          ; F2
          mov    bx,09h
          call   PLAY
          mov    dx,07F0h          ; D2
          mov    bx,03h
          call   PLAY
          mov    dx,0990h          ; H1
          mov    bx,06h
          call   PLAY
          mov    dx,08E8h          ; C2
          mov    bx,12h
          call   PLAY
          mov    dx,0712h          ; E2
          mov    bx,12h
          call   PLAY

  ;-------------------------------------

          mov    dx,08E8h          ; C2
          mov    bx,06h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0E24h          ; E1
          mov    bx,06h
          call   PLAY
          mov    dx,0BE4h          ; G1
          mov    bx,06h
          call   PLAY
          mov    dx,0D59h          ; F1
          mov    bx,06h
          call   PLAY
          mov    dx,0FDFh          ; D1
          mov    bx,06h
          call   PLAY
          mov    dx,11D1h          ; C1
          mov    bx,24h
          call   PLAY

  ;-------------------------------------

          mov    ah,4Ch            ; Powrot do DOS-u.
          int    21h

  ;-------------------------------------

  impulsy dw     00h               ; Komorka pamieci do przechowywania
                                   ; wartosci odliczonych impulsow
                                   ; zegarowych (co ok. 55 milisek.).

  ;---------------------------------------------------------------------------

  PLAY PROC NEAR            ; Procedura grania nut

          mov    al,0B6h    ; Informacja, ze bedzie ustawiana wartosc licznika.
          out    43h,al     ; Wyslanie do portu.
          mov    ax,dx      ; Wartosc licznika z DX do akumulatora.
          out    42h,al     ; Wyslij do portu mniej znaczacy bajt licznika.
          mov    al,ah
          out    42h,al     ; i bardziej znaczacy bajt licznika.

                            ; Zegar 8253 jest juz zaprogramowany na czestotliwosc
                            ; odpowiadajaca danej wartosci licznika, czyli odp. nute.
                            ; Teraz trzeba wlaczyc dzwiek.

          in     al,61h     ; Pobranie stanu generatora.
          or     al,3       ; Uruchomienie dzwieku - bity 0 i 1 = 1
          out    61h,al     ; Wyslanie do portu.

  ;--------------------------------------------------------------------
  ; Odliczenie czasu (wartosc z rejestru BX razy 55 milisekund.)
  ;--------------------------------------------------------------------
          push   cx         ; Przechowaj CX i DX na stosie.
          push   dx
          mov    cx,bx      ; Dlugosc interwalu.

  duza_petla:
          push   cx         ; Przechowanie licznika duzej petli.
          xor    ah,ah
          int    1Ah        ; Pobranie liczby impulsow zegara:
                            ; w CX:DX - liczba impulsow zegara.
          mov    impulsy,dx ; Przechowanie mniej znaczacej czesci.

  mala_petla:
          xor    ah,ah
          int    1Ah
          cmp    impulsy,dx ; Czy liczba impulsow jest taka sama?
          je     mala_petla

                            ; Liczba impulsow zmienila sie...

          pop    cx         ; Odtworzenie licznika duzej petli.
          loop   duza_petla ; Petla naliczania impulsow zegara.
          pop    dx         ; Odtworzenie rejestrow procesora
          pop    cx

  ;--------------------------
  ; Wylaczenie generatora
  ;--------------------------
          in     al,61h     ; Pobranie stanu generatora.
          and    al,0FCh    ; Kasowanie bitow dzwieku - bity 0 i 1 = 0
          out    61h,al     ; Wyslanie do portu.
          ret

  PLAY ENDP

  ;-----------------------------------------------------
  ; Obrazek i napis do wyswietlenia na ekranie za pomoca
  ; standardowej funkcji nr 09h przerwania nr 21h
  ;-----------------------------------------------------

  PIC db 38 dup (20h), 2Ah, 20 dup (20h), 0Fh, 0Ah, 0Dh
      db 18 dup (20h), 0Fh, 19 dup (20h), 2Ah, 0Ah, 0Dh
      db 36 dup (20h),"**�**", 29 dup (20h), 0Fh, 0Ah, 0Dh
      db 33 dup (20h),"*****�*****", 0Ah, 0Dh
      db 08 dup (20h), 0Fh, 27 dup (20h),"**�**", 0Ah, 0Dh
      db 34 dup (20h), "****�****              ", 0Ah, 0Dh
      db 20 dup (20h), 0Fh, 10 dup (20h),"*******�*******", 0Ah, 0Dh
      db 27 dup (20h), "***********�***********", 0Ah, 0Dh
      db 34 dup (20h), "****�****", 0Ah, 0Dh
      db 31 dup (20h), "******���******", 0Ah, 0Dh
      db 13 dup (20h), 0Fh, 14 dup (20h), "*********���*********", 0Ah, 0Dh
      db 25 dup (20h), "************���************", 0Ah, 0Dh
      db 21 dup (20h), 16 dup (2Ah), "���", 16 dup (2Ah), 15 dup (20h), 0Fh, 0Ah, 0Dh
      db 17 dup (20h), 20 dup (2Ah), "���", 20 dup (2Ah), 0Ah, 0Dh
      db 13 dup (20h), 24 dup (2Ah), "���", 24 dup (2Ah), 0Ah, 0Dh
      db 37 dup (20h), "���", 0Ah, 0Dh
      db "        *", 28 dup (20h), "���", 28 dup (20h), 2Ah, 0Ah, 0Dh
      db "       *�*", 27 dup (20h), "���", 27 dup (20h), "*�*", 0Ah, 0Dh
      db "      **�**", 55 dup (20h), "**�**", 0Ah, 0Dh
      db "    ****�****         WESOLYCH SWIAT  BOZEGO NARODZENIA         ****�****", 0Ah, 0Dh
      db "  ******�******        I SZCZESLIWEGO NOWEGO 1994 ROKU        ******�******", 0Ah, 0Dh
      db "        �                    ZYCZY  JACEK SP7LSM                    �", 0Ah, 0Dh, 24h

           end start



             



Poniżej widać zrzut ekranu z okna DOSBOX-a, w którym uruchomiłem program CICHANOC.COM.

Pliki CICHANOC.ASM i CICHANOC.COM można pobrać jako archiwum cichanoc.tgz.



DOSBOX - screenshot






Strona główna