                MINI KURS PISANIA PROGRAMW TSR W ASEMBLERZE

4. WADY I ZALETY MULTIPLEX INTERRUPT

     Na  pocztku  wyjanijmy  sobie o co w ogle chodzi w tytule tej czci.
Ot Multiplex Interrupt jest to jedno z przerwa programowych (to znaczy nie
wywoywanych  przez  sprzt,  jak  np.  przerwanie  zegara, ale tylko poprzez
instrukcj  int).  Ma  numer 2fh i suy do bardzo wielu przydatnych rzeczy a
w szczeglnoci niesie pomoc w programach rezydentnych. Caa istota Multiplex
Interrupt  (w  skrcie  MxI)  polega  na  utworzeniu  "acucha",  do ktrego
dopinaj  si  kolejne  programy  wykorzystujce  je - TSRy. Kady program ma
przydzielony swj numer identyfikacyjny, po ktrym moe pozna, czy odwoanie
MxI  dotyczy  tego  rezydenta,  czy jakiego innego. W trakcie instalacji TSR
odczytuje  wektor  przerwania  2fh  i  ustawia nowy na swoj procedur. Teraz
kiedy  przyjdzie  przerwanie i w rejestrze AH jest jego numer identyfikacyjny
to  oznacza,  e  do  niego przyszo zlecenie (o tym bdzie dalej) i on je ma
obsuy.  Jeeli  w  AH jest inny numer, TSR przekazuje sterowanie pod stary
adres  (zapamitany  podczas  instalacji).  Powysze  tumaczenie  jest  do
zawie, dlatego podam troch konkretw:

Przerwanie 2Fh
Nazwa:          Obsuga rwnoczesnych procesw
Wywoanie:      AH = numer procesu (czyli ID TSRa)
                     01h  - rezydentna cz polecenia PRINT
                     02h  - rezydentna cz polecenia ASSIGN
                     03h  - rezydentna cz polecenia SHARE
                     80h-0ffh - dostpne dla innych procesw
                AL = 0
Powrt:         AL - stan zainstalowania
                     00h  - nie zainstalowany, mona zainstalowa
                     01h  - nie zainstalowany, nie mona zainstalowa
                     0ffh - zainstalowany

Opis:           Przerwanie    organizuje    rwnoczesn    prac    programw
                rezydentnych   dostpnych  z  dowolnego  procesu.  Pierwotnie
                dotyczyo  tylko  polecenia  systemowego  PRINT. Kady proces
                instaluje  si  w  kolejce  (poprzez  kolejne przechwytywanie
                tego  przerwania).  W  przypadku  wywoania  zlecenia  proces
                sprawdza,  czy  zlecenie  go  dotyczy,  jeli  nie  to oddaje
                sterowanie   poprzedniemu   w   kolejce.   W   rejestrze   AL
                przekazywany  jest kod zlecenia. Standardowo zlecenie numer 0
                oznacza pytanie o to, czy program jest zainstalowany.

Z powyszego opisu widzimy, jak prosta jest zasada dziaania MxI, wszystkie
rezydentne polecenia DOSu maj wbudowan obsug swoich funkcji przez to
przerwanie (np. moemy poleceniu PRINT kaza zatrzyma wszystkie wydruki znajc
numer zlecenia, ktre mamy mu przekaza), na przykad:

  mov  ax,0103h    ; 01-PRINT, 03-zatrzymanie drukowania
  int  2fh

     Dziaanie Multiplex Interrupt w naszym rezydencie zaley tylko od naszej
inwencji,  poza  oczywicie  zleceniem  nr 0, ktre ma przekaza informacj o
zainstalowaniu  programu.  Wtedy  moemy  stwierdzi,  czy  TSR jest obecny w
pamici,  pomimo  e  po  nim  by instalowany inny program rezydentny, ktry
rwnie  przechwyci  to  samo  przerwanie (w przypadku sekundnika przerwanie
zegara).  Poza  tym  moemy  doda  rwnie  nasze  nowe zlecenia, np. zmiana
kolorw  cyfr  bez  reinstalacji  programu, podawanie segmentu, w ktrym jest
obecny  kod  TSRa i tak dalej. Przykadw mona znale bez liku, jeli tylko
dysponuje  si  rozwinit wyobrani. W naszym nowym przykadowym rezydencie
(ile  razy mona obrabia i ulepsza sekundnik?) zastosujemy procedur, ktra
bdzie "wraliwa" na ID procesu nr 90h (dlaczego tak? wymylio mi si, mona
poda  numer  od  80h  w gr) i zlecenia nr 0 oraz 1. Czasem takie zaoenia
mog  nie  przynie  spodziewanych rezultatw, gdy w pamici bdzie inny TSR
reagujcy  rwnie  na  numer 90h - przy takich obawach mona napisa funkcj
przeszukujc  kolejne  numery  od  80h (sprawdzamy zleceniem 0, czy rezydent
jest  zainstalowany)  i  zatrzymujc  si  na  pierwszym  wolnym.  My jednak
przyjmiemy,  e  90h  jest  dla  nas  wystarczajcy  i  nic si nie powtrzy.
Zlecenie  nr 0 bdzie suyo do sprawdzania, czy nasz rezydent jest obecny w
pamici  (czyli  bdziemy w AL zwraca 0ffh) oraz przy okazji czytania numeru
segmentu,  w  jakim jest on zainstalowany (zwracamy w BX). Natomiast zlecenie
nr  1  bdzie  nam  podawa  w ES:DI adres cigu znakw (zakoczonego znakiem
dolara,  tak  jak  w  napisach  w  DOSie)  z wersj zainstalowanego TSRa. Sam
program  rezydentny  bdzie  realizowa trywialne zadanie - podepniemy go pod
przerwanie  klawiatury  i  przy kadym naciniciu klawisza bdzie generowany
dwik  o  dugoci  zalenej  od  czasu  nacinicia  (czyli po stwierdzeniu
nacinicia  wczymy  dwik  PC  Speakera, a przy puszczeniu wyczymy). Do
tego bdzie jeszcze aktywna kombinacja Alt-Ctrl-Ins, przeczajca nam dwik
(na  zasadzie  wczony  -  wyczony  -  wczony itd). I znw to samo - sam
program nie jest przeznaczony do uywania w konkretnych celach (czy sekundnik
komu si do czego przyda?), ale do zobrazowania technik pisania TSRw.

     Przy  usuwaniu  programu  rezydentnego  z  pamici (nazwijmy go roboczo:
beep)  naley  pamita o sprawdzeniu MxI, czy TSR jest obecny, jak rwnie o
odczytaniu wektora przerwania klawiatury (int 9h), poniewa nie moemy usun
TSRa  i  odtworzy wykorzystywanych przez niego przerwa, kiedy po nim zosta
zainstalowany  inny  rezydent  (bo  w  ten  sposb  odcilibymy  od "funkcji
yciowych"  rwnie  ten  inny  program). Jednak jest na to sposb - odcinamy
tylko   dziaanie   kliku   i   kombinacji  Alt-Ctrl-Ins  poprzez  ustawienie
odpowiedniej  flagi  w  obszarze  TSRa (mona by byo te po to wymyli nowe
zlecenie  MxI,  ale  po co kombinowa, gdy po odczytaniu numeru segmentu kodu
zleceniem  0  mamy  dostp  do  obszaru  zmiennych  beepa),  nazywa  si  ona
'niemamnie' i gdy nie jest rwna 0 to TSR zachowuje si tak, jakby go w ogle
nie  byo. Gdyby beep rezerwowa sobie dodatkowe bloki pamici naleao by je
rwnie zwolni. Pamitajmy rwnie o tym, aby w czasie instalacji sprawdzi,
czy  przypadkiem  ju  wczeniej  beep  nie  by  instalowany, a jeeli tak -
wywietli stosowny komunikat, no i oczywicie zwolni blok pamici zajmowany
przez rodowisko programu. Nasz TSR nie bdzie tym razem sprawdza parametrw
podanych w linii polece w poszukiwaniu 'u', natomiast po uruchomieniu bdzie
si  instalowa  w  pamici,  a  po  powtrnym  uruchomieniu  -  usuwa  (lub
dezaktywowa).

     Po  wywoaniu  przez  system  przerwania  klawiatury, pod ktre jestemy
podpici  moemy  odczyta  kod wcinitego klawisza z portu 60h (in al,60h),
jest  to tzw. scan-code klawisza, czyli najoglniej mwic jego kolejny numer
na  klawiaturze.  Klawisz  Insert  ma  scan-code rwny 52h, natomiast ten sam
klawisz  przy  zwolnieniu  wysya  kod o 80h wikszy (z ustawionym najwyszym
bitem),  czyli  0d2h.  Klawiatura  rozszerzona  101-klawiszowa wysya ponadto
dodatkowe  kody informujce, czy nacinito Ins z klawiatury numerycznej, czy
szary  Ins  z  dodatkowego bloku - jest wtedy przed scan-code klawisza Insert
wysyany  kod  0e0h  -  my  po odebraniu takiego kodu przekazujemy sterowanie
bezporednio  do oryginalnej procedury. W programie beep bdziemy reagowa na
puszczenie  klawisza  Insert  ze  wzgldu  na  samopowtarzanie  przy duszym
naciniciu (gdyby TSR reagowa na nacinicie, obserwowalibymy naprzemienne
wczanie  i wyczanie funkcji programu). Fakt wcinicia jednoczenie Alt i
Ctrl  rozpoznamy  badajc  obszar zmiennych BIOSu (komrka 0:417h, bity 2 i 3
ustawione,   traktowaa   o  tym  szerzej  cz  3  kursu).  Po  rozpoznaniu
"korzystnej"   kombinacji   (Alt-Ctrl-Ins)   zmieniamy  warto  wewntrznego
przecznika  (zmienna  flipflop), po czym zwracamy sterowanie do oryginalnej
procedury obsugi przerwania klawiatury. Gdybymy nie chcieli tego robi (np.
przechwyci  i  "zdusi"  wszystkie  nacinicia  klawisza X) i nie przesya
sterowania  pod  oryginalny adres (czyli do poprzedniego programu doczonego
do  int  9h, a w kocu do procedury w BIOSie wpisujcej kod ASCII klawisza do
bufora klawiatury), naleaoby wykona nastpujcy fragment kodu, wymagany do
poprawnego powrotu do gwnego programu instrukcj iret:

  in   al,61h      ;+ znak dla kontrolera klawiatury, e zakoczylimy
  mov  ah,al       ;+ obsug przerwania
  or   al,80h      ;+
  out  61h,al      ;+
  mov  al,ah       ;+
  out  61h,al      ;+
  mov  al,20h      ;- znak dla kontrolera przerwa
  out  20h,al      ;- (tzw. EOI - End Of Interrupt)

Do wczania dwiku w goniku su instrukcje:

  in   al,61h
  or   al,3        ; ustawiamy bity: 0 i 1
  out  61h,al

Do wyczania:

  in   al,61h
  and  al,0fch     ; zerujemy bity: 0 i 1
  out  61h,al

     Na  pocztku  w  trakcie instalacji TSRa moemy jeszcze ustawi wysoko
dwiku  wysyajc  2  bajty  wartoci  licznika do timera (ktry obsuguje i
zegar,   i   generator   gonika).   Warto  licznika  to:  1193181/f,  f -
czstotliwo  dwiku.  Z  tego wynika, e chcc ustawi wysoko dwiku na
440  Hz  naley  ustawi licznik na 1193181/440 = 2712, czyli 0a98h. Wysyamy
kolejno:  kod  operacji  (0b6h) do portu 43h, nastpnie modszy bajt licznika
(98h) do portu 42h, a potem starszy bajt (0ah):

  mov  al,0b6h
  out  43h,al
  mov  al,98h
  out  42h,al
  mov  al,0ah
  out  42h,al

     W  naszym  przykadowym  programie  beep  moliwo ustawienia wysokoci
dwiku  nie  zostaa  wykorzystana,  moecie  to zrobi w swoich programach.
Mona  te  rwnie  pokusi  si  o  napisanie  rezydenta,  ktry  po kadym
nacinitym  klawiszu  bdzie zmienia wysoko tonu, biorc j na przykad z
tablicy.  Wtedy  przy  pisaniu tekstu komputer bdzie gra muzyk! To tyle na
dzi, zobaczymy, co przyniesie kolejny odcinek.
