Ocenite etot tekst:






   Vvedenie
      Soglasheniya o chislah, prinyatye v etoj knige.
      Vvedenie

   Glava 1. Sistemnye resursy.
      Razdel 1. Reviziya sistemnyh resursov.
        Dostup k mikrosheme interfejsa s periferiej 8255.
        Opredelenie tipa IBM PC.
        Opredelenie versii MS DOS.
        Opredelenie chisla i tipov adapterov displeya.
        Opredelenie chisla i tipa diskovyh nakopitelej.
        Opredelenie chisla i tipa periferijnyh ustrojstv.
        Reviziya kolichestva pamyati.
      Razdel 2. Upravlenie preryvaniyami.
        Programmirovanie kontrollera preryvanij 8259.
        Zapret/razreshenie otdel'nyh apparatnyh preryvanij.
        Napisanie sobstvennogo preryvaniya.
        Dopolnenie k sushchestvuyushchemu preryvaniyu.
      Razdel 3. Upravlenie programmami.
        Manipulyacii s pamyat'yu.
        Zapusk odnoj programmy iz drugoj.
        Ispol'zovanie komand interfejsa s pol'zovatelem iz programmy.
        Sohranenie programmy v pamyati posle zaversheniya.
        Zagruzka i zapusk programmnyh overleev.
        Preobrazovanie programm iz tipa .EXE v tip .COM.
   Glava 2. Tajmery i zvuk.
      Razdel 1. Ustanovka i chtenie tajmera.
        Programmirovanie mikroshemy tajmera 8253/8254.
        Ustanovka/chtenie vremeni.
        Ustanovka/chtenie daty.
        Ustanovka/chtenie chasov real'nogo vremeni.
        Zaderzhka programmnyh operacij.
        Operacii zaprogrammirovannye vo vremeni.
        Upravlenie rabotoj v real'nom vremeni.
        Generaciya sluchajnyh chisel s pomoshch'yu mikroshemy tajmera.
      Razdel 2. Sozdanie zvuka.
        Programmirovanie generatora zvuka 76496 (tol'ko PCjr).
        Generaciya tona.
        Generaciya zvuka odnovremenno s drugimi dejstviyami.
        Gudok dinamika.
        Generaciya nabora tonov.
        Generaciya stroki tonov, odnovremenno s drugimi operaciyami.
        Sozdanie plavnogo perehoda tonov.
        Sozdanie zvukovyh effektov.
        Odnovremennaya generaciya raznyh zvukov.
   Glava 3. Klaviatura.
      Razdel 1. Upravlenie klaviaturoj.
        Ochistka bufera klaviatury.
        Proverka simvolov v bufere.
        Ozhidat' vvod simvola i ne vyvodit' ego na ekran.
        Ozhidanie nazhatiya klavishi i eho na ekran.
        Priem simvola bez ozhidaniya.
        Poluchenie stroki simvolov.
        Proverka/ustanovka statusa klavish-pereklyuchatelej.
        Napisanie procedury  vvoda  s klaviatury obshchego naznacheniya.
        Pereprogrammirovanie preryvaniya klaviatury.
Razdel 2. Dostup k otdel'nym klavisham.
        Ispol'zovanie klavish  <BackSpace>,  <Enter>,  <Escape> i <Tab>.
        Ispol'zovanie klavish-pereklyuchatelej: <Shift>, <Ctrl>  i  <Alt>.
        Ispol'zovanie klavish-pereklyuchatelej: NumLock,  CapsLock, Ins i ScrollLock.
        Ispol'zovanie cifrovoj dopolnitel'noj klaviatury i  kla-
        vish peremeshcheniya kursora.
        Ispol'zovanie funkcional'nyh klavish.
        Pereprogrammirovanie otdel'nyh klavish.
        Sozdanie makroopredelenij dlya otdel'nyh klavish.
        Sozdanie procedury obrabotki Ctrl-Break.
        Pereprogrammirovanie klavishi PrtSc.
      Razdel 3: Svodka kodov klavish i primenenij.
        Predopredelennoe ispol'zovanie klavish.
        Svodnaya tablica skan-kodov.
        Svodnaya tablica kodov ASCII
        Svodka kodov psevdografiki dlya postroeniya ramok.
        Svodnaya tablica rasshirennyh kodov.
   Glava 4. Vyvod na terminal.
      Razdel 1. Upravlenie vyvodom na terminal.
        Programmirovanie kontrollera displeya 6845.
        Ustanovka/proverka rezhima displeya.
        Ustanovka atributov/cvetov simvolov.
        Ustanovka cveta granicy ekrana.
        Ochistka chasti/vsego ekrana.
        Pereklyuchenie mezhdu videoadaptorami.
      Razdel 2. Upravlenie kursorom.
        Ustanovka kursora v absolyutnuyu poziciyu.
        Otnositel'noe pozicionirovanie kursora
        Vklyuchenie i vyklyuchenie kursora.
        Izmenenie formy kursora.
        CHtenie/sohranenie/vosstanovlenie pozicii kursora.
        Sozdanie al'ternativnyh tipov kursora.
      Razdel 3. Vyvod simvolov na ekran.
        Vyvod na ekran odnogo simvola.
        Vyvod stroki simvolov na ekran.
        CHtenie simvola i ego atributov v dannoj pozicii.
        Sozdanie special'nyh simvolov.
        Svodka dannyh dlya opisaniya simvolov.
      Razdel 4. Vyvod tochechnoj grafiki.
        Ustanovka cvetov dlya tochechnoj grafiki.
        Risovanie tochki na ekrane (monohromnyj, cvetnoj i PCjr).
        Risovanie tochki na ekrane (EGA).
        Opredelenie cveta tochki ekrana.
        Risovanie linij na ekrane.
        Zapolnenie oblastej ekrana.
        Graficheskij vyvod s ispol'zovaniem simvolov psevdografiki.
      Razdel 5. Sdvig ekrana i stranicy.
        Vertikal'nyj sdvig tekstovogo ekrana.
        Sdvig tekstovogo ekrana gorizontal'no.
        Pereklyuchenie mezhdu tekstovymi stranicami.
        Sdvig mezhdu stranicami teksta.
   Glava 5. Diskovye nakopiteli.
      Razdel 1. Upravlenie raspredeleniem diska.
        CHtenie tablicy razmeshcheniya fajlov.
        Opredelenie dostupnogo diskovogo prostranstva.
        Poluchenie/ustanovka razmera fajla.
        Vosstanovlenie  posle  oshibok,  svyazannyh  s  nehvatkoj
        prostranstva na diske.
Razdel 2. Rabota s katalogami diska.
        CHtenie/izmenenie kornevogo kataloga.
        Sozdanie/udalenie podkataloga.
        CHtenie/izmenenie podkataloga.
        Poluchenie/ustanovka tekushchego kataloga.
        Poluchenie/ustanovka vremeni  i daty poslednego dostupa k
        fajlu.
        Spryatannye i zashchishchennye ot zapisi fajly.
        CHtenie/izmenenie metki toma.
      Razdel 3. Podgotovka k rabote s fajlami.
        Ustanovka/proverka nakopitelya po umolchaniyu.
        Sozdanie/udalenie fajla.
        Otkrytie/zakrytie fajla.
        Pereimenovanie fajla;  izmenenie pozicii fajla v kataloge.
        Podgotovka k fajlovym operaciyam.
        Analiz informacii komandnoj stroki.
      Razdel 4. CHtenie i zapis' fajla.
        Programmirovanie kontrollera NGMD 765 i mikroshemy prya-
        mogo dostupa k pamyati 8237.
        CHtenie/zapis' opredelennyh sektorov.
        Zapis' v posledovatel'nye fajly.
        CHtenie iz posledovatel'nyh fajlov.
        Zapis' v fajly pryamogo dostupa.
        CHtenie iz fajlov pryamogo dostupa.
        Proverka dannyh posle operacij chteniya/zapisi.
        Opredelenie diskovyh oshibok i vosstanovlenie posle nih.
   Glava 6. Printer.
      Razdel 1. Upravlenie rabotoj printera.
        Inicializaciya  porta  printera/povtornaya  inicializaciya
        printera.
        Proverka togo, chto printer svyazan s mashinoj.
        Interpretaciya  oshibok printera i  vosstanovlenie  posle nih.
        Pereklyuchenie mezhdu dvumya ili neskol'kimi printerami.
      Razdel 2. Ustanovka specifikacij pechati.
        Ustanovka tekstovogo i graficheskogo rezhimov.
        Upravlenie rasstoyaniem mezhdu strokami.
        Upravlenie dvizheniem bumagi.
        Upravlenie polozheniem pechatayushchej golovki.
        Ustanovka pozicij tabulyacii.
        Izmenenie shrifta pechati.
        Sravnenie vozmozhnostej printerov IBM.
      Razdel 3. Posylka dannyh na printer.
        Vyvod tekstovyh ili graficheskih dannyh na printer.
        Vyravnivanie pravogo polya.
        Proporcional'naya pechat'.
        Pechat' special'nyh simvolov.
        Kopirovanie ekrana na printer (damp ekrana).
   Glava 7. Vvod/vyvod.
      Razdel 1. Dostup k posledovatel'nomu portu.
        Programmirovanie mikroshemy UART 8250.
        Inicializaciya posledovatel'nogo porta.
        Ustanovka tekushchego kommunikacionnogo porta.
        Opredelenie statusa kommunikacionnogo porta.
        Inicializaciya i upravlenie modemom.
        Peredacha dannyh.
        Poluchenie dannyh.
        Posylka/poluchenie  dannyh s  pomoshch'yu  kommunikacionnogo
        preryvaniya.
        Svodka upravlyayushchih kodov, ispol'zuemyh pri kommunikacii.
      Razdel 2. Sozdanie drajvera ustrojstva.
        Sozdanie zagolovka drajvera.
        Sozdanie strategii ustrojstva.
        Sozdanie obrabotchika preryvaniya ustrojstva.
        Dostup k drajveru ustrojstva.
        Obnaruzhenie i analiz oshibok ustrojstva.
      Razdel 3. Ispol'zovanie special'nyh ustrojstv vvoda/vyvoda.
        CHtenie/zapis' s kassetnogo magnitofona.
        CHtenie pozicii svetovogo pera.
        Poluchenie analogovogo vvoda cherez igrovoj port.
        Poluchenie cifrovogo vvoda iz igrovogo porta.

   Prilozheniya.
      Prilozhenie A.  Dvoichnye i shestnadcatirichnye chisla i  adre-
      saciya pamyati.
      Prilozhenie B. Bitovye operacii v Bejsike.
      Prilozhenie V. Osnovnye svedeniya ob yazyke assemblera.
      Prilozhenie G.  Vklyuchenie assemblernyh procedur v programmy
      na Bejsike.
      Prilozhenie D. Ispol'zovanie drajvera ustrojstva ANSI.SYS.
      Prilozhenie E. Nabor instrukcij mikroprocessora 8088.
      Prilozhenie ZH. Nabor instrukcij mikroprocessora 80286.
      Prilozhenie Z. Tolkovyj slovar' IBM PC.







   Odnoj  iz pervyh zadach posle zagruzki zadachi yavlyaetsya proverka
kuda my popali: na kakom  tipe  IBM  PC  zapushchena  zadacha?... pod
kakoj versiej MS DOS?... skol'ko imeetsya pamyati?...  vse li neob-
hodimoe oborudovanie  prisutstvuet? Imeetsya tri sposoba polucheniya
etoj informacii.  Naimenee elegantnyj sposob - sprosit' ob etom u
pol'zovatelya (no znaet li on otvety?). Namnogo luchshe poluchit' vsyu
dostupnuyu  informaciyu  iz ustanovki pereklyuchatelej  na  sistemnoj
plate.  No eta ustanovka ne vsegda sootvetstvuet real'nosti. Poe-
tomu  luchshe vsego ispol'zovat' tret'yu vozmozhnost' - poluchit' prya-
moj dostup k trebuemomu oborudovaniyu  ili prochitat' nuzhnuyu infor-
maciyu iz oblasti dannyh BIOS.  Poskol'ku ustanovka pereklyuchatelej
mozhet sluzhit' otpravnoj tochkoj  dlya  polucheniya trebuemoj informa-
cii, to etot razdel nachinaetsya s obsuzhdeniya mikroshemy,  soderzha-
shchej etu informaciyu - mikroshemy interfejsa s periferiej 8255.
   Programma mozhet  poluchit'  dostup  k oborudovaniyu tol'ko dvumya
sposobami.  Ona mozhet obratit'sya k lyubomu iz portov vvoda/vyvoda,
sootvetstvuyushchemu   prisoedinennomu   oborudovaniyu  (obychno byvaet
zanyata  lish' malaya dolya iz 65535 vozmozhnyh adresov portov).   Ili
programma mozhet obratit'sya k lyubomu iz bolee chem millionu adresov
operativnoj  pamyati.  Svodnaya tablica adresov portov privedena  v
[7.3.0]. Na ris. 1-1  pokazano  kak  raspredeleny v pamyati opera-
cionnaya sistema i programmy.





   Mikroshema  interfejsa s periferiej Intel 8255 - luchshee mesto,
s kotorogo nado nachinat', chtoby poluchit'  informaciyu ob imeyushchemsya
oborudovanii. |ta mikroshema prednaznachena dlya mnogih celej.  Ona
soobshchaet ob  ustanovke  pereklyuchatelej  na  sistemnoj plate.  Ona
prinimaet dlya komp'yutera vvod s klaviatury.  Ona upravlyaet  ryadom
periferijnyh ustrojstv, vklyuchaya mikroshemu tajmera 8253. Iz mashin
semejstva  IBM  PC  tol'ko AT ne ispol'zuet mikroshemu  8255;  on
hranit informaciyu ob oborudovanii  vmeste s chasami real'nogo vre-
meni  v special'noj mikrosheme s nezavisimym pitaniem.  Odnako AT
ispol'zuet te zhe adresa portov, chto  i 8255, dlya raboty s klavia-
turoj i upravleniya mikroshemoj tajmera.
   Mikroshema 8255 imeet tri odnobajtnyh registra, nazyvaemyh  ot
porta A do porta C. Adresa etih portov ot 60H do 62H sotvetstven-
no.  Vse tri porta mozhno chitat', no pisat' mozhno tol'ko v port B.
Dlya PC, ustanovka bita 7 porta B v  1 izmenyaet informaciyu, soder-
zhashchuyusya v porte A.  Analogichno dlya PC ustanovka bita 2 opredelyaet
soderzhimoe  chetyreh  mladshih  bitov  porta  C, a ustanovka bita 3
delaet to zhe samoe dlya XT. Soderzhimoe etih registrov sleduyushchee:

   Port A (60H)
      kogda v porte B bit 7=0
         bity 0-7 PC,XT,PCjr,AT: 8-bitnye skan-kody s klaviatury
      kogda v porte B bit 7=1 dlya PC
         bit 0    PC: 0 = net nakopitelej na disketah
             1    PC: ne ispol'zuetsya
           2-3    PC: chislo bankov pamyati na sistemnoj plate
           4-5    PC: tip displeya (11 = monohromnyj,
                      10 = cvetnoj 80*25, 01 = cvetnoj 40*25)
           6-7    PC: chislo nakopitelej na disketah

   Port B (61H)
         bit 0    PC,XT,PCjr: upravlyaet kanalom 2 tajmera 8253
             1    PC,XT,PCjr: vyvod na dinamik
             2    PC: vybor soderzhimogo porta C
                  PCjr: 1 = simvol'nyj rezhim, 0 = graficheskij
             3    PC,PCjr: 1 = kassetnyj motor vyklyuchen
                  XT: vybor soderzhimogo porta C
             4    PC,XT: 0 = razreshenie OZU
                  PCjr: 1 = zapret dinamika i motora kassety
             5    PC,XT: 0 = razreshenie oshibok shchelej rasshireniya
             6    PC,XT: 1 = razreshenie chasov klaviatury
           5-6    PCjr: vybor dinamika (00 = 8253, 01 = kasseta,
                  10 = vvod/vyvod, 11 = mikroshema 76496)
             7    PC: vybor soderzhimogo porta A
                  PC,XT: podtverzhdenie klaviatury


   Port C (62H)
      kogda v porte B bit 2=1 dlya PC ili bit 3=1 dlya XT
      bity 0-3    PC: nizhnyaya polovina pereklyuchatelya 2 konfi-
                  guracii (OZU na plate rasshireniya)
             0    PCjr: 1 = vvedennyj simvol poteryan
             1    XT: 1 = est' mat. soprocessor
                  PCjr: est' karta modema
             2    PCjr: est' karta NGMD
           2-3    XT: chislo bankov pamyati na sistemnoj plate
             3    PCjr: 0 = 128K pamyati
             4    PC,PCjr: vvod s kassety
                  XT: ne ispol'zuetsya
             5    PC,XT,PCjr: vyhod kanala 2 8253
             6    PC,XT: 1 = proverka oshibok shchelej rasshireniya
                  PCjr: 1 = dannye s klaviatury
             7    PC,XT: 1 = kontrol' oshibok chetnosti
                  PCjr: 0 = kabel' klaviatury podsoedinen
      kogda v porte B bit 2=0 dlya PC ili bit 3=0 dlya XT
      bity 0-3    PC: verhnyaya polovina pereklyuchatelya 2 konfi-
                  guracii (ne ispol'zuetsya)
           0-1    XT: tip displeya (11 = monohromnyj,
                  10 = cvetnoj 80*25, 01 = cvetnoj 40*25)
           2-3    XT: chislo nakopitelej NGMD (00 = 1 i t.d.)
           4-7    PC,XT: to zhe, chto i s ustanovlennymi bitami

   Otmetim,  chto 0 v odnom iz bitov registra sootvetstvuet  usta-
novke pereklyuchatelya "off".
   AT hranit  informaciyu  o  konfiguracii  v  mikrosheme MC146818
firmy  Motorola, vmeste s chasami real'nogo vremeni.  On vovse  ne
imeet mikroshemy 8255, hotya dlya upravleniya  mikroshemoj tajmera i
priema  dannyh s klaviatury ispol'zuyutsya te zhe samye adresa  por-
tov.  Mikroshema imeet 64 registra, pronumerovannyh ot 00 do 3FH.
Dlya  chteniya  registra  nuzhno snachala poslat' ego nomer v  port  s
adresom 70H, a zatem  prochitat'  ego  cherez  port  71H. Razlichnye
parametry  konfiguracii  obsuzhdayutsya  na  posleduyushchih  stranicah.
Privedem zdes' tol'ko kratkuyu svodku:

   Nomer registra               Ispol'zovanie
       10H             tip nakopitelya NGMD
       12H             tip nakopitelya fiksirovannogo diska
       14H             periferiya
       15H             pamyat' na sistemnoj plate (mladshij bajt)
       16H             pamyat' na sistemnoj plate (starshij bajt)
       17H             obshchaya pamyat' (mladshij bajt)
       18H             obshchaya pamyat' (starshij bajt)
       30H             pamyat' sverh 1 megabajta (mladshij bajt)
       31H             pamyat' sverh 1 megabajta (starshij bajt)


   Vysokij uroven'.

   V dannoj knige imeetsya  mnozhestvo primerov dostupa k etim por-
tam.  Nizhe privoditsya programma na Bejsike, ustanavlivayushchaya chislo
diskovyh nakopitelej, prisoedinennyh  k IBM PC. Prezhde chem prochi-
tat' dva starshih bita porta A, bit 7 porta B dolzhen byt' ustanov-
len v 1.  Sushchestvenno, chto Vy  dolzhny vernut' znachenie etogo bita
nazad v 0 pered dal'nejshej rabotoj, inache klaviatura budet zaper-
ta i dlya  vosstanovleniya  rabotosposobnosti  mashiny  Vam pridetsya
vyklyuchit'  ee.  Bejsik ne pozvolyaet dvoichnoe predstavlenie chisel,
chto zatrudnyaet rabotu  s  cepochkami  bitov.  Prostaya podprogramma
mozhet  zamenit' lyuboe celoe vplot' do 255 (maksimal'noe znachenie,
kotoroe mozhet prinimat' nomer porta) na vos'misimvol'nuyu dvoichnuyu
stroku.   Posle  etogo strokovaya funkciya MID$ pozvolyaet  vyrezat'
nuzhnye bity dlya analiza. Osnovy bitovyh operacij v Bejsike opisa-
ny v prilozhenii B.

100 A = INP(&H61)            'poluchaem znachenie iz porta B
110 A = A OR 128             'ustanavlivaem bit 7
120 OUT &H61,A               'posylaem bajt nazad v port B
130 B = INP(&H60)            'poluchaem znachenie iz porta A
140 A = A AND 128            'sbrasyvaem bit 7
150 OUT &H61,A               'vosstanavlivaem znachenie porta B
160 GOSUB 1000               'preobrazuem v dvoichnuyu stroku
170 NUMDISK$ = RIGHT$(B$,1)  'poluchaem nulevoj bit
180 IF D$ = 1 THEN NUMDISK = 0: GOTO 230 'net diskov
190 C$ = LEFT$(B$,2)         'berem dva starshih bita stroki
200 TALLEY = 0               'peremennaya dlya chisla diskov
210 IF RIGHT$(C$,1) = "1" THEN TALLEY = 2 'berem starshij bit
220 IF LEFT$(C$,1) = "1" THEN TALLEY = TALLEY + 1 'i mladshij
230 TALLEY = TALLEY + 1      'schet nachinaetsya s 1, a ne s 0
                             'teper' imeem chislo nakopitelej
1000 '''Podprogramma preobrazovaniya bajta v dvoichnuyu stroku
1010 B$ = ""                 'zavodim stroku
1020 FOR N = 7 TO 0 STEP -1  'proverka ocherednoj stepeni 2
1030 Z = B - 2^N             '
1040 IF Z >= 0 THEN B = Z: B$ = B$+"1" ELSE B$ = B$+"0"
1050 NEXT                    'povtoryaem dlya kazhdogo bita
1060 RETURN                  'vse zakoncheno

   Nizkij uroven'.

   Assemblernaya programma poluchaet chislo imeyushchihsya diskovyh nako-
pitelej tem zhe sposobom, chto  i  v  vysheprivedennom  primere,  no
bolee  prosto.  Napominaem, chto nel'zya zabyvat' o  vosstanovlenii
pervonachal'nogo znacheniya v porte B.

   IN   AL,61H          ;poluchaem znachenie iz porta B
   OR   AL,10000000B    ;ustanavlivaem bit 7 v 1
   OUT  61H,AL          ;zamenyaem bajt
   IN   AL,60H          ;poluchaem znachenie iz porta A
   MOV  CL,6            ;podgotovka dlya sdviga AL
   SHR  AL,CL           ;sdvigaem 2 starshih bita na 6 pozicij
   INC  AL              ;nachinaem schet s 1, a ne s 0
   MOV  NUM_DRIVES,AL   ;poluchaem chislo nakopitelej
   IN   AL,61H          ;podgotovka k vosstanovleniyu porta B
   AND  AL,01111111B    ;sbrasyvaem bit 7
   OUT  61H,AL          ;vosstanavlivaem bajt





   Imeyutsya problemy sovmestimosti mezhdu razlichnymi tipami IBM PC.
Dlya  togo chtoby programma mogla rabotat' na lyubom iz IBM PC,  is-
pol'zuya vse ego vozmozhnosti,  neobhodimo  chtoby ona mogla oprede-
lit'  tip mashiny, v kotoruyu ona zagruzhena.  |ta informaciya soder-
zhitsya vo vtorom s konca bajte pamyati  po adresu FFFFE v ROM-BIOS,
s ispol'zovaniem sleduyushchih klyuchevyh chisel.

             Komp'yuter                Kod
                PC                     FF
                XT                     FE
                PCjr                   FD
                AT                     FC

   Vysokij uroven'.

   V Bejsike nado prosto ispol'zovat' PEEK dlya chteniya znacheniya:

100 DEF SEG = &HF000        'ukazyvaem na verhnie 64K pamyati
110 X = PEEK(&HFFFE)        'chitaem vtoroj s konca bajt
120 IF X = &HFD THEN ...    '... togda eto PCjr

   Nizkij uroven'.

   V yazyke assemblera:

;--- Opredelenie tipa komp'yutera:
   MOV  AX,0F000H           ;ukazyvaet ES na PZU
   MOV  ES,AX               ;
   MOV  AL,ES:[0FFFEH]      ;poluchaem bajt
   CMP  AL,0FDH             ;eto PCjr?
   JE   INITIALIZE_JR       ;perehodim na inicializaciyu





   Po  mere razvitiya MS DOS k nej dobavlyalis' novye  vozmozhnosti,
mnogie iz kotoryh sushchestvenno  oblegchayut  napisanie  opredelennyh
chastej programmy po sravneniyu s predydushchimi versiyami. CHtoby imet'
garantiyu chto programma budet rabotat'  s lyuboj versiej MS DOS ona
dolzhna  ispol'zovat'  tol'ko funkcii, dostupnye v MS DOS 1.0.   V
sisteme predusmotreno  preryvanie,  vozvrashchayushchee  nomer versii MS
DOS.   |to  chislo mozhet ispol'zovat'sya dlya proverki  vypolnimosti
Vashej programmy.  Minimal'no, programma mozhet pri starte vydavat'
soobshchenie ob oshibke, soobshchaya chto ej nuzhna drugaya versiya MS DOS.

   Srednij uroven'.

   Funkciya  30H  preryvaniya 21H vozvrashchaet nomer versii  MS  DOS.
Starshij nomer versii (2  iz  2.10)  vozvrashchaetsya  v AL, a mladshij
nomer  versii (10 iz 2.10) vozvrashchaetsya v AH (obratite  vnimanie,
chto mladshij nomer .1 vozvrashchaet  znachenie  AH, a ne 1H). AL mozhet
soderzhat' 0, chto ukazyvaet na versiyu MS DOS men'shuyu chem 2.0.  |to
preryvanie menyaet soderzhimoe  registrov  BX i CX, v kotoryh vozv-
rashchaetsya znachenie 0.

;--- Opredelenie versii MS DOS:
   MOV   AH,30H            ;nomer funkcii polucheniya versii
   INT   21H               ;poluchit' nomer versii
   CMP   AL,2              ;proverka na versiyu 2.h
   JL    WRONG_DOS         ;esli men'she 2, to vydat' soobshchenie





   Programme  mozhet okazat'sya neobhodima informaciya o tom,  budet
li ona rabotat' v  sisteme  s  monohromnym  adapterom,  s cvetnoj
graficheskoj kartoj ili s EGA, a takzhe o nalichii vtorogo adaptera.
V  punkte  [4.1.6]  ob®yasneno kak peredat' upravlenie  ot  odnogo
adaptera k drugomu.  Bajt  statusa oborudovaniya, hranyashchijsya v ob-
lasti  dannyh  ROM-BIOS  po adresu 0040:0010  soobshchaet  ustanovku
pereklyuchatelya 1,  kotoryj  pokazyvaet  kakaya  iz  kart aktivna. V
principe dolzhny imet' znachenie 11 dlya monohromnoj karty, 10 - dlya
cvetnoj karty 80*25, 01 - dlya  cvetnoj  karty 40*25 i 00 dlya EGA.
Odnako  pri nalichii EGA on mozhet ustanovit' bity otlichnymi ot 00,
v zavisimosti ot ustanovki ego sobstvennyh pereklyuchatelej. Poeto-
mu Vy dolzhny snachala drugimi sredstvami ustanovit' nalichie EGA, a
zatem, esli ego net, to  po  dannym  BIOS  opredelit' yavlyaetsya li
aktivnym  cvetnoj ili monohromnyj adapter.  Dlya proverki  nalichiya
EGA nado prochitat' bajt po adresu  0040:0087. Esli on raven 0, to
EGA otsutstvuet.  Esli etot bajt nenulevoj, to kogda bit 3=0, EGA
yavlyaetsya aktivnym adapterom, a  kogda on raven 1, to aktiven vto-
roj adapter.
   Kogda  prisutstvuet EGA, to proverka nalichiya monohromnogo  ili
cvetnogo adaptera osushchestvlyaetsya zapis'yu znacheniya v registr adre-
sa kursora mikroshemy 6845 [4.1.1] i posleduyushchego chteniya znacheniya
i proverki ih na sovpadenie. Dlya  monohromnoj karty poshlite 0FH v
port  3B4H, chtoby ukazat' na registr kursora, a zatem prochitat' i
zapisat' adres kursora cherez port 3B5H. Sootvetstvuyushchie porty dlya
cvetnoj karty 3D4H i 3D5H. Kogda karta otsutstvuet, to port vozv-
rashchaet znachenie 0FFH; no poskol'ku eto znachenie mozhet soderzhat'sya
v registre, to nedostatochno prostoj proverki na eto znachenie.
   Imeyutsya dva dobavochnyh voprosa, na kotorye mogut potrebovat'sya
otvety pri nalichii  EGA:  skol'ko  imeetsya  pamyati na ego karte i
kakoj  tip  monitora  podsoedinen? Dlya opredeleniya  tipa  displeya
prover'te bit 1 po  adresu  0040:0087;  kogda  on  ustanovlen, to
podsoedinen  mmonohromnyj displej, a kogda on raven nulyu -  cvet-
noj.  Esli Vasha programma  ispol'zuet cvetnoj graficheskij rezhim s
350  strokami,  to nado takzhe opredelit' prisoedinen  li  displej
IRGB ili  R'G'B'RGB,  gde  poslednyaya  abbreviatura  sootvetstvuet
uluchshenomu  cvetnomu  displeyu IBM.  |to  opredelyaetsya  ustanovkoj
chetyreh pereklyuchatelej na karte EGA.  Ustanovka etih pereklyuchate-
lej vozvrashchaetsya v CL pri obrashchenii k funkcii 12H preryvaniya 10H.
Cepochka chetyreh mladshih bitov  dolzhna  byt'  0110 dlya uluchshennogo
cvetnogo  displeya.  Ta zhe samaya funkciya soobshchaet i nalichie pamyati
na karte EGA.  Ona vozvrashchaet  BL,  soderzhashchij 0 dlya 64K, 1 - dlya
128, 2 - dlya 192 i 3 - dlya polnyh 256K pamyati displeya.



   Vysokij uroven'.

   Privedennye fragmenty koda opredelyayut tip tekushchego monitora  i
rezhim ego raboty, a  takzhe  opredelyayut  kakie tipy videoadapterov
imeyutsya v mashine:

100 '''opredelenie aktivnogo adaptera
110 DEF SEG = &H40         'ukazyvaem na oblast' dannyh BIOS
120 X = PEEK(&H87)         'proverka na nalichie EGA
130 IF X = 0 THEN 200      'EGA otsutstvuet, idem dal'she
140 IF X AND 8 = 0 THEN... 'aktivnyj monitor EGA
 .
 .
200 X = PEEK(&H10)         'chitaem bajt statusa oborudovaniya
210 Y = X AND 48           'vydelyaem bity 4 i 5
220 IF Y = 48 THEN ...     '... togda monohromnyj (00110000)
230 IF Y = 32 THEN ...     '... togda cvetnoj 80*25 (00100000)
240 IF Y = 16 THEN ...     '... togda cvetnoj 40*25 (00010000)

   Sleduyushchij  primer  proveryaet nalichie monohromnoj karty,  kogda
aktivnoj yavlyaetsya karta  EGA  ili  cvetnaya.  Tot  zhe primer mozhno
ispol'zovat' dlya proverki nalichiya cvetnoj karty esli ispol'zovat'
adresa portov &H3D4 i &H3D5.

100 '''proverka nalichiya monohromnoj karty
110 OUT &H3B4,&HF          'adres registra kursora
120 X = INP(&H3B5)         'chtenie i sohranenie znacheniya
130 OUT &H3B5,100          'posylaem v registr lyuboe znachenie
140 IF INP(&H3B5)<>100 THEN... 'esli karta est' - vernetsya to zhe
150 OUT &H3B5,X            'vosstanavlivaem znachenie registra

   Nizkij uroven'.

   Privedennye primery sootvetstvuyut primeram na Bejsike.

;--- Opredelenie aktivnogo adaptera:
   MOV   AX,40H        ;ukazyvaem ES na oblast' dannyh BIOS
   MOV   ES,AX         ;
   MOV   AL,ES:[87H]   ;proveryaem nalichie EGA
   CMP   AL,0          ;
   JE    NO_EGA        ;esli 0040:0087 = 0, to EGA net
   TEST  AL,00001000B  ;EGA est', proveryaem bit 3
   JNZ   EGA_NOT_ACTIVE;esli bit 3=1, to EGA neaktiven
    .
    .
EGA_NOT_ACTIVE:
   MOV   AL,ES:[10H]   ;proveryaem bajt statusa displeya
   AND   AL,00110000B  ;vydelyaem bity 4 i 5
   CMP   AL,48         ;eto monohromnaya karta?
   JE    MONOCHROME    ;perehod esli da

   Predpolagaya  nalichie monohromnoj karty proverim ustanovlena li
cvetnaya karta (neaktivnaya):



;--- Ustanovlena li neaktivnaya cvetnaya karta?
   MOV   DX,3D4H       ;ukazyvaem na registr adresa 6845
   MOV   AL,0FH        ;zaprashivaem registr kursora
   OUT   DX,AL         ;ukazyvaem na registr
   INC   DX            ;ukazyvaem na registr dannyh
   IN    AL,DX         ;poluchaem tekushchee znachenie
   XCNG  AH,AL         ;sohranyaem znachenie
   MOV   AL,100        ;testovoe znachenie 100
   OUT   DX,AL         ;posylaem ego
   IN    AL,DX         ;schityvaem ego snova
   CMP   AL,100        ;sravnivaem znacheniya
   JNE   NO_CARD       ;perehod esli net karty
   XCNG  AH,AL         ;inache est' cvetnaya karta
   OUT   DX,AL         ;togda vosstanavlivaem znachenie





   Na  vseh  mashinah  krome AT (kotoryj budet  obsuzhdat'sya  nizhe)
registry mikroshemy 8255 interfejsa  s periferiej soderzhat infor-
maciyu o tom, skol'ko NGMD imeet mashina.  V primerah [1.1.1] poka-
zano kak poluchit' etu  informaciyu.   Informaciya  opredelyayushchaya tip
diska soderzhitsya v tablice razmeshcheniya fajlov (FAT) diska, kotoraya
sledit za ispol'zovaniem diskovogo prostranstva.  Pervyj bajt FAT
soderzhit odin iz sleduyushchih kodov:

      Kod                    Tip diska

       FF            dvuhstoronnij, 8 sektorov
       FE            odnostoronnij, 8 sektorov
       FD            dvuhstoronnij, 9 sektorov
       FC            odnostoronnij, 9 sektorov
       F9            dvuhstoronnij, 15 sektorov
       F8            fiksirovannyj disk

   Sama tablica razmeshchenie fajlov ne yavlyaetsya  fajlom.  Ona mozhet
byt' schitana pri pomoshchi funkcij DOS  ili BIOS neposredstvenno chi-
tayushchih opredelennye sektora diska. V  punkte  [5.1.1]  soderzhitsya
vsya informaciya neobhodimaya dlya nahozhdeniya i chteniya FAT. K schast'yu,
operacionnaya  sistema  obespechivaet  funkciyu,  kotoraya  vozvrashchaet
identifikacionnyj bajt diska.
   Dannye BIOS ne pokazyvayut chislo  zhestkih diskov v sisteme, tak
kak pereklyuchateli prednaznacheny tol'ko dlya gibkih diskov.  Odnako
Vy mozhete ispol'zovat' ukazannuyu funkciyu operacionnoj sistemy dlya
poiska nakopitelej.  Ona vozvrashchaet znachenie 0CDH, vmesto  odnogo
iz upomyanutyh kodov, kogda  nakopiteli  otsutstvuyut.  Nado prosto
proveryat'  vse  bol'shie i bol'shie nomera nakopitelej, do teh  por
poka ne budet obnaruzheno ukazannoe znachenie.
   AT unikalen v tom smysle, chto  ego  informaciya  o konfiguracii
govorit  kakoj tip nakopitelya ispol'zuetsya.  |tu informaciyu mozhno
poluchit' iz porta s  adresom  71H,  predvaritel'no  poslav  nomer
registra v port 70H. Dlya NGMD nomer registra raven 10H.  Informa-
ciya o pervom  nakopitele  soderzhitsya  v bitah 7-4, a o vtorom - v
bitah 3-0. V oboih sluchayah cepochka bitov 0000 govorit ob otsutst-
vii nakopitelya, 0001 - o dvuhstoronnem nakopitele s plotnost'yu 48
dorozhek  na dyujm, a 0010 - o nakopitele bol'shoj emkosti (96 doro-
zhek na dyujm).  Informaciya o  fiksirovannom diske soderzhitsya v re-
gistre 12H. I snova bity 7-4 i 3-0 sootvetstvuyut pervomu i vtoro-
mu nakopitelyam.  0000 ukazyvaet na otsutstvie nakopitelya.  Drugie
15 vozmozhnyh znachenij opisyvayut emkost' i konstrukciyu nakopitelya.
|ti kody slozhnye; esli Vam  po  kakoj-to  prichine potrebuetsya eta
informaciya, obratites' k tehnicheskomu rukovodstvu po AT.

   Srednij uroven'.

   Funkciya  1CH preryvaniya 21H vozvrashchaet informaciyu ob ukazannom
nakopitele.  Pomestite nomer  nakopitelya v DL, prichem 0 = nakopi-
tel'  po  umolchaniyu, 1 = A, i t.d.  Pri vozvrashchenii  DX  soderzhit
chislo klasterov v FAT, AL  -  chislo  sektorov  v klastere, a CX -
chislo bajtov v sektore.  DS:BX ukazyvaet na bajt, soderzhashchij  kod
identifikacii diska iz FAT, soglasno privedennoj tablice.  V sle-
duyushchem primere opredelyaetsya tip nakopitelya A:


;---opredelenie tipa diska
   MOV   AH,1CH        ;funkciya MS DOS
   MOV   DL,1          ;vybor nakopitelya A
   INT   21H           ;poluchenie informacii
   MOV   DL,[BX]       ;poluchenie tipa nakopitelya
   CMP   DL,0FDH       ;dvuhstoronnij, 9 sektorov?
   JE    DBL_9         ;i t.d.

   BIOS AT imeet funkciyu, soobshchayushchuyu obshchie parametry nakopitelej.
|to funkciya 8 preryvaniya 13H.  Ona vozvrashchaet chislo nakopitelej v
DL, maksimal'noe chislo storon nakopitelya v DH, maksimal'noe chislo
sektorov v CL i dorozhek v CH, a  kod  statusa oshibki nakopitelya v
AH (sm. punkt [5.4.8]).
   Drugaya funkciya BIOS AT vozvrashchaet tip nakopitelya.  |to funkciya
15H preryvaniya 13H, kotoraya trebuet nomera nakopitelya v DL.  V AH
vozvrashchaetsya  kod,  prichem 0 = net nakopitelya,  1 =  disketa  bez
obnaruzheniya izmenenij, 2 = disketa s obnaruzheniem izmenenij i 3 =
fiksirovannyj disk. V sluchae fiksirovannogo diska v CX:DX vozvra-
shchaetsya chislo sektorov po 512 bajt.





   Pri starte ROM-BIOS  proveryaet   prisoedinennoe  oborudovanie,
soobshchaya  o  rezul'tatah svoej proverki v registr  statusa.   |tot
registr zanimaet dva bajta, nachinaya  s 0040:0010. Nizheprivedennye
znacheniya  bitov otnosyatsya ko vsem mashinam, poka ne ogovoreno  ob-
ratnoe:
   bit 0    esli 1, to prisutstvuet NGMD
   1        XT,AT:1 = est' mat. soprocessor (PC,PCjr:ne ispol'z.)
   2-3      11 = bazovaya pamyat' 64K (AT:ne ispol'zuetsya)
   4-5      Aktivnyj videoadapter (11 = monohromnyj,
            10 = cvetnoj 80*25, 01 = cvetnoj 40*25)
   6-7      chislo NGMD (esli bit 0 = 1)
   8        PCjr:0 = est' DMA (PC,XT,AT:ne ispol'zuetsya)
   9-11     chislo adapterov kommunikacii
   12       1 = est' igrovoj port (AT:ne ispol'zuetsya)
   13       PCjr:est' serijnyj printer (PC,XT,AT:ne ispol'z.)
   14-15    chislo prisoedinennyh printerov

   Bol'shaya chast' informaciya rasshifrovyvaetsya primitivno. No obra-
tite vnimanie, chto informaciya o diskovyh nakopitelyah raspredelena
mezhdu bitami 0 i 6-7. Znachenie 0 v bitah 6-7 ukazyvaet, chto  ime-
etsya odin diskovyj nakopitel'; chtoby uznat' ob otsutstvii nakopi-
telej nado proverit' bit 0.
   CHislo portov kommunikacii mozhet byt' polucheno iz oblasti  dan-
nyh BIOS. BIOS otvodit chetyre 2-bajtnyh polya dlya hraneniya bazovyh
adresov vplot' do chetyreh  COM  portov  (MS DOS ispol'zuet tol'ko
dva iz nih). Bazovyj adres - eto mladshij iz adresov portov, otno-
syashchihsya k gruppe portov, imeyushchih dostup k dannomu kanalu kommuni-
kacii.  |ti chetyre polya nachinayutsya s adresa 0040:0008. Portu COM1
sootvetstvuet adres :0008, a COM2  - 000A. Esli eto pole soderzhit
0, to sootvetstvuyushchij port otsutstvuet. Takim obrazom, esli slovo
po adresu :0008 otlichno ot  nulya,  a po adresu 000A - nulevoe, to
imeetsya odin port kommunikacii.
   AT  hranit  informaciyu o periferii v registre  14H  mikroshemy
konfiguracii. Snachala zapishite  14H v port s adresom 70H, a zatem
prochitajte soderzhimoe registra cherez port 71H. Vot znachenie bitov
etogo registra:

   bity 7-6   00 = 1 NGMD, 01 = 2 NGMD
        5-4   01 = vyvod na cvetnoj displej, 40 strok
              10 = vyvod na cvetnoj displej, 80 strok
              11 = vyvod na monohromnyj displej
        3-2   ne ispol'zuetsya
          1   1 = imeetsya mat. soprocessor
          0   0 = net NGMD, 1 = imeetsya NGMD

   Vysokij uroven'.

   V Bejsike  nuzhno  prosto  prochitat'  bajty  statusa iz oblasti
dannyh BIOS. V prilozhenii B ob®yasneno vypolnenie bitovyh operacij
v Bejsike. V privedennom primere  proverka nalichiya diskovyh nako-
pitelej dostigaetsya proverkoj chetnosti  mladshego bajta statusnogo
registra (chetnyj - net nakopitelej).


100 DEF SEG = 0          'ukazyvyaem na dno pamyati
110 X = PEEK(&H410)      'poluchaem mladshij bajt registra
120 IF X MOD 2 = 0 THEN 140 'on chetnyj - net nakopitelej
130 PRINT "Imeetsya disk" 'inache imeetsya nakopitel'
140 GOTO 160             'idem ko vtoromu soobshcheniyu
150 PRINT "Net nakopitelej"  'vtoroe soobshchenie
160 ...                  'prodolzhaem...

   Proverka nalichiya COM1:

100 DEF SEG = 40H        'ukazyvaem na oblast' dannyh BIOS
110 PORT = PEEK(0) + 256*PEEK(1) 'poluchaem slovo so smeshcheniem 0
120 IF PORT = 0 THEN...  '... to net adaptera COM1

   Srednij uroven'.

   Preryvanie 11H BIOS vozvrashchaet bajt statusa oborudovaniya v AX.
Na  vhode nichego podavat' ne nado.  V primere opredelyaetsya  chislo
diskovyh nakopitelej.

; ---poluchenie chisla diskovyh nakopitelej:
   INT   11H         ;poluchaem bajt statusa
   TEST  AL,0        ;imeyutsya nakopiteli?
   JZ    NO_DRIVES   ;perehod, esli net
   AND   AL,1100000B ;vydelyaem bity 5-6
   MOV   CL,5        ;podgotovka k sdvigu registra
   SHR   AL,CL       ;sdvig vpravo na 5 bitov
   INC   AL          ;dobavlyaem 1, t.k. otschet idet s 1

   Nizkij uroven'.

   Assemblernaya  programma  rabotaet  tak  zhe, kak i programma na
Bejsike.   V primere chitaetsya informaciya o konfiguracii  dlya  AT,
opredelyaya ustanovlen li matematicheskij soprocessor:

   MOV   AL,14H      ;nomer registra
   OUT   70H,AL      ;posylaem zapros
   IN    AL,71H      ;chitaem registr
   TEST  AL,10B      ;proveryaem bit 1
   JZ    NO_COPROCESSOR ;esli ne ustanovlen, to soprocessora net





   Vopros:  "Skol'ko  imeetsya pamyati?",- mozhet imet' tri  smysla.
O kakom kolichestve pamyati  soobshchayut  pereklyuchateli, ustanovlennye
na  sistemnoj plate? Skol'ko mikroshem pamyati real'no ustanovleno
v mashine? I, nakonec, skol'ko ostaetsya  svobodnoj pamyati, kotoruyu
DOS  mozhet  ispol'zovat' dlya vypolneniya  Vashih  programm?  Mashina
mozhet imet' 10 bankov pamyati po  64K, no pereklyuchateli mogut uka-
zyvat'  na nalichie tol'ko 320K, ostavlyaya polovinu pamyati dlya  ka-
kih-libo special'nyh celej.  A  kak  mozhet Vasha programma uznat',
skol'ko  iz dostupnyh 320K ona mozhet ispol'zovat', uchityvaya,  chto
drugoe programmnoe obespechenie mozhet byt' zagruzheno rezidentnym v
verhnyuyu ili nizhnyuyu chast' pamyati?
   Otvet na kazhdyj vopros mozhno poluchit' svoim sposobom. Dlya PC i
XT ustanovka  pereklyuchatelej  mozhet  byt'  prosto prochitana cherez
port B mikroshemy interfejsa s periferiej 8255.  V punkte [1.1.1]
opisano kak eto delaetsya. BIOS  hranit  dvuhbajtnuyu peremennuyu po
adresu  0040:0013, kotoraya soobshchaet chislo  kilobajt  ispol'zuemoj
pamyati. Dlya PCjr bit 3 porta  62H  (port C mikroshemy 8255) raven
nulyu,  kogda  mashina imeet dobavochnye 64K pamyati.  AT daet  osobo
polnuyu informaciyu o pamyati.   Registry 15H (mladshij) i 16H (star-
shij)  mikroshemy informacii o konfiguracii govoryat skol'ko pamyati
ustanovleno na sistemnoj plate  (vozmozhny  tri  znacheniya: 0100H -
dlya  256K, 0200H - dlya 512K i 0280H dlya 512K plyus 128K  na  plate
rasshireniya). Pamyat' kanala vvoda/vyvoda dlya AT soobshchaetsya regist-
rami  17H i 18H (s inkrementom 512K).  Pamyat'  sverh 1  megabajta
dostupna cherez registry  30H  i  31H  (opyat'  s inkrementom 512K,
vplot' do 15 megabajt).  Esli AT imeet 128K na plate  rasshireniya,
to ustanovlen bit 7 registra  33.   Vo  vseh sluchayah nado snachala
poslat' nomer registra v port 70H, a zatem prochitat' znachenie  iz
porta 71H.
   Legko  napisat'  programmu,  kotoraya  pryamo  testiruet nalichie
pamyati cherez opredelennye intervaly adresnogo prostranstva.  Pos-
kol'ku minimal'naya porciya pamyati 16  kilobajt, to dostatochno pro-
verit' odnu yachejku pamyati v kazhdom 16-kilobajtnom segmente, chtoby
ubedit'sya, chto vse 16K  prisutstvuyut.  Kogda dannaya yachejka pamyati
otsutstvuet,  to  pri chtenii iz nee poluchaem znachenie  233.   Dlya
proverki mozhno zapisat' v yachejku proizvol'noe  chislo, otlichnoe ot
233 i srazu zhe schitat' ego.  Esli vmesto poslannogo chisla vozvra-
shchaetsya 233, to sootvetstvuyushchij bank pamyati otsutstvuet. Ne prime-
nyajte  etot sposob na AT, gde pri popytke pisat' v nesushchestvuyushchuyu
pamyat' vstupaet v dejstvie  vstroennaya  obrabotka  nesushchestvuyushchej
pamyati.   Diagnostika AT nastol'ko horosha, chto Vy mozhete  celikom
polozhit'sya na sistemnuyu informaciyu o konfiguracii.
   Pamyat'  postoyanno  zanimaetsya  chastyami  operacionnoj  sistemy,
drajverami ustrojstv, rezidentnymi programmami obrabotki preryva-
nij i upravlyayushchimi blokami MS DOS.  Pri proverke bankov pamyati Vy
ne  dolzhny  vnosit' neobratimyh  izmenenij v  soderzhimoe  pamyati.
Snachala nado sohranit' znachenie, hranyashcheesya v testiruemoj yachejke,
zatem proverit' ee i vosstanovit' pervonachal'noe znachenie.
   Imeetsya eshche odna problema. Esli Vasha procedura hotya by vremen-
no modificiruet svoj kod, to eto mozhet privesti k krahu.  Poetomu
dlya proverki nado vybirat' takuyu yachejku iz bloka 64K, kotoraya  ne
budet zanyata tekstom Vashej procedury.  Dlya etogo pomestite proce-
duru testirovaniya vperedi programmy, a dlya testirovaniya  vyberite


yachejku so smeshcheniem ravnym smeshcheniyu dlya kodovogo segmenta. Napri-
mer,  esli  registr kodovogo segmenta soderzhit 13E2,  to  segment
nachinaetsya so smeshcheniya 13E2 vo  vtorom  64K-bajtnom bloke pamyati.
Poskol'ku Vasha podprogramma proverki ne mozhet nahodit'sya po etomu
adresu, to Vy mozhete bezopasno  proveryat'  znachenie  3E2 v kazhdom
bloke.   Zapret  preryvanij [1.2.2] pozvolyaet ne  bespokoit'sya  o
modifikacii  koda  iz-za  apparatnyh  preryvanij,  kotorye  mogut
proishodit' vo vremya proverki.
   Opredelenie  kolichestva pamyati real'no dostupnoj  operacionnoj
sisteme takzhe trebuet nekotorogo  fokusa.  Kogda programma pervyj
raz poluchaet upravlenie, to DOS otvodit ej vsyu dostupnuyu  pamyat',
vklyuchaya verhnyuyu oblast'  pamyati,  soderzhashchuyu  nerezidentnuyu chast'
DOS (kotoraya avtomaticheski perezagruzhaetsya, esli ona byla modifi-
cirovana). Dlya zapuska drugoj  programmy iz tekushchej ili dlya togo,
chtoby  sdelat' programmu podhodyashchej dlya mnogopol'zovatel'soj sis-
temy, neobhodimo urezat' programmu do trebuemogo razmera. V punk-
te [1.3.1] opisano kak eto sdelat' s pomoshch'yu funkcii 4AH preryva-
niya 21H.
   |ta zhe funkciya mozhet byt' ispol'zovana dlya rasshireniya otveden-
noj  pamyati.  Poskol'ku programme otvoditsya vsya dostupnaya  pamyat'
pri zagruzke, to takoe rasshirenie  nevozmozhno pri starte. Esli Vy
poprobuete  sdelat'  eto, to budet ustanovlen  flag  perenosa,  v
registre AX poyavitsya kod oshibki  8, a v registre BX budet vozvra-
shcheno  maksimal'noe  chislo dostupnyh 16-bajtnyh  paragrafov.   |ta
informaciya kak raz i nuzhna.  Znachit nado vydat' zapros so slishkom
bol'shim  znacheniem  v registre BX ( skazhem, F000H paragrafov),  a
zatem vypolnite preryvanie.   Pozabot'tes' o tom, chtoby vypolnit'
etu  funkciyu v samom nachale programmy, poka registr ES eshche  imeet
nachal'noe znachenie.

   Vysokij uroven'.

   Interpretator  Bejsika  ispol'zuet  tol'ko 64K (hotya operatory
PEEK  i POKE pozvolyayut dostup k pamyati za predelami  64K).   Dolya
pamyati dostupnaya v  nastoyashchij  moment  vozvrashchaetsya funkciej FRE.
|ta funkciya imeet fiktivnyj argument, kotoryj mozhet byt' chislovym
ili simvol'noj strokoj.  BYTES  =  FRE(x)  peredaet v BYTES chislo
svobodnyh bajtov. BYTES = FRE(x$) delaet to zhe samoe.  No stroko-
vyj argument vynuzhdaet ochistku oblasti dannyh pered tem kak vozv-
ratit'  chislo bajtov.  Zametim, chto esli razmer  rabochej  oblasti
ustanavlivaetsya s pomoshch'yu  operatora CLEAR, to kolichestvo pamyati,
soobshchaemoe  funkciej  FRE  budet na ot 2.5 do 4  kilobajt  men'she
iz-za potrebnostej rabochej oblasti interpretatora.
   Translyator Bejsika ne nakladyvaet ogranichenie 64K na summarnyj
ob®em koda i dannyh.  No sam kompilyator ogranichen tem kolichestvom
pamyati, kotoroe on mozhet ispol'zovat' pri kompilyacii.  Esli etogo
prostranstva  nedostatochno,  to unichtozh'te  vse  nenuzhnye  nomera
strok pri pomoshchi klyucha  kompilyacii  /N.  Mozhno takzhe ispol'zovat'
bolee korotkie imena peremennyh.


   Srednij uroven'.

   Preryvanie 12H BIOS proveryaet ustanovku pereklyuchatelej i vozv-
rashchaet v AX kolichestvo kilobajt  pamyati  v sisteme.  |ta velichina
vychislyaetsya  iz ustanovki registrov mikroshemy 8255 ili, dlya  AT,
mikroshemy  konfiguracii/chasov.   Vhodnyh  registrov net.  Imejte
vvidu,  chto  ustanovka  pereklyuchatelej mozhet byt'  nevernoj,  chto
ogranichivaet dostovernost' takogo podhoda.
   Dlya opredeleniya  chisla  16-bajtnyh  paragrafov,  dostupnyh dlya
DOS, ispol'zujte funkciyu 4AH preryvaniya 21H.  ES dolzhen imet'  to
zhe znachenie, chto pri starte zadachi:

;---opredelenie chisla paragrafov dostupnyh dlya DOS
   MOV   AH,4AH        ;ukazyvaem nuzhnuyu funkciyu
   MOV   BX,0FFFFH     ;trebuem slishkom bol'shuyu pamyat'
   INT   21H           ;BX soderzhit chislo dostupnyh paragrafov

   AT ispol'zuet funkciyu 88H  preryvaniya 15H dlya proverki nalichiya
rasshirennoj pamyati, kotoraya ishchet pamyat' vne adresnogo prostranst-
va processora v obychnom rezhime  adresacii.  Govoryat, chto ona ishchet
pamyat' za otmetkoj 1 megabajta.  Pri etom na sistemnoj plate dol-
zhno  byt' ot 512 do 640 kilobajt pamyati, chtoby eta funkciya  rabo-
tala.  CHislo kilobajtnyh blokov rasshirennoj pamyati vozvrashchaetsya v
AX.

   Nizkij uroven'.

   Pervyj primer proveryaet  chislo  bankov  pamyati po 64K v pervyh
desyati 64-kilobajtnyh segmentah pamyati.  Esli Vy budete proveryat'
starshie 6 bankov pamyati, to imejte vvidu, chto imeyutsya videobufer,
nachinaya  s  B000:0000 (i, vozmozhno, A000:0000) i PZU,  nachinaya  s
F000:0000 (i, vozmozhno, C000:0000).

;---proverka kazhdogo banka pamyati:
   CLI                  ;zapret apparatnyh preryvanij
   MOV   AX,CS          ;poluchaem znachenie kodovogo segmenta
   AND   AX,0FFFH       ;sbrasyvaem starshie 4 bita
   MOV   ES,AX          ;pomeshchaem ukazatel' v ES
   MOV   DI,0           ;DI schitaet chislo bankov pamyati
   MOV   CX,10          ;budem proveryat' 10 bankov
   MOV   BL,'X'         ;dlya proverki ispol'zuem 'X'
NEXT:
   MOV   DL,ES:[0]      ;sohranyaem znachenie testiruemoj yachejki
   MOV   ES:[0],BL      ;pomeshchaem 'X' v etu yachejku
   MOV   DH,ES:[0]      ;chitaem testiruemuyu yachejku
   MOV   ES:[0],DL      ;vosstanavlivaem znachenie
   CMP   DH,'X'         ;sovpadaet s tem, chto pisali?
   JNE   GO_AHEAD       ;esli net, to bank otsutstvuet
   INC   DI             ;uvelichivaem chislo bankov
GO_AHEAD:
   MOV   AX,ES          ;gotovim uvelichenie ukazatelya
   ADD   AX,1000H       ;ukazyvaem na sleduyushchie 64K
   MOV   ES,AX          ;vozvrashchaem ukazatel' v ES
   LOOP  NEXT           ;obrabatyvaem sleduyushchij bank
   STI                  ;razreshaem apparatnye preryvaniya





   Preryvaniya  eto gotovye procedury, kotorye komp'yuter  vyzyvaet
dlya vypolneniya opredelennoj zadachi. Sushchestvuyut apparatnye i prog-
rammnye preryvaniya.  Apparatnye preryvaniya iniciiruyutsya apparatu-
roj, libo s sistemnoj platy,  libo s  karty rasshireniya. Oni mogut
byt'  vyzvany signalom mikroshemy tajmera, signalom ot  printera,
nazhatiem klavishi na klaviature i mnozhestvom  drugih prichin. Appa-
ratnye preryvaniya ne koordiniruyutsya s rabotoj programmnogo  obes-
pecheniya. Kogda vyzyvaetsya preryvanie, to processor ostavlyaet svoyu
rabotu,  vypolnyaet  preryvanie, a zatem vozvrashchaetsya  na  prezhnee
mesto. Dlya togo chtoby imet'  vozmozhnost' vernut'sya tochno v nuzhnoe
mesto programmy, adres etogo mesta (CS:IP) zapominaetsya na steke,
vmeste s registrom flagov.  Zatem v CS:IP zagruzhaetsya adres prog-
rammy obrabotki preryvaniya i ej peredaetsya  upravlenie. Programmy
obrabotki  preryvanij inogda nazyvayut drajverami preryvanij.  Oni
vsegda zavershayutsya  instrukciej  IRET  (vozvrat  iz  preryvaniya),
kotoraya zavershaet process, nachatyj preryvaniem, vozvrashchaya  starye
znacheniya CS:IP i registra  flagov, tem samym davaya programme voz-
mozhnost' prodolzhit' vypolnenie iz togo zhe sostoyaniya.
   S  drugoj storony, programmnye preryvaniya na samom dele nichego
ne preryvayut.  Na samom dele eto obychnye procedury, kotorye vyzy-
vayutsya  Vashimi programmami dlya vypolneniya rutinnoj raboty,  takoj
kak priem nazhatiya klavishi na klaviature ili vyvod na ekran. Odna-
ko  eti  podprogrammy soderzhatsya ne vnutri Vashej  programmy, a  v
operacionnoj sisteme i mehanizm  preryvanij  daet Vam vozmozhnost'
obratit'sya k nim. Programmnye preryvaniya mogut vyzyvat'sya drug iz
druga. Naprimer, vse preryvaniya  obrabotki vvoda s klaviatury DOS
ispol'zuyut preryvaniya obrabotki vvoda s klaviatury BIOS dlya polu-
cheniya simvola iz bufera klaviatury.  Otmetim, chto apparatnoe pre-
ryvaenie  mozhet poluchit' upravlenie pri  vypolnenii  programmnogo
preryvaniya. Pri  etom  ne  voznikaet  konfliktov,  tak kak kazhdaya
podprogramma obrabotki preryvaniya sohranyaet znacheniya vseh ispol'-
zuemyh eyu registrov i  zatem  vosstanavlivaet  ih pri vyhode, tem
samym ne ostavlyaya sledov togo, chto ona zanimala processor.
   Adresa programm preryvanij nazyvayut vektorami.  Kazhdyj  vektor
imeet dlinu chetyre bajta. V  pervom slove hranitsya znachenie IP, a
vo vtorom - CS.  Mladshie 1024 bajt pamyati soderzhat vektora prery-
vanij, takim obrazom imeetsya mesto  dlya 256 vektorov. Vmeste vzya-
tye  oni  nazyvayutsya tablicej vektorov.  Vektor dlya preryvaniya  0
nachinaetsya s yachejki 0000:0000, preryvaniya  1 - s 0000:0004, 2 - s
0000:0008 i t.d. Esli posmotret' na chetyre bajta, nachinaya s adre-
sa 0000:0020, v kotoryh soderzhitsya vektor preryvaniya 8H (preryva-
nie  vremeni sutok), to Vy obnaruzhite tam A5FE00F0.  Imeya  vvidu,
chto mladshij bajt  slova  raspolozhen  snachala i chto poryadok IP:CS,
eto  4-bajtnoe znachenie perevoditsya v F000:FEA5.   |to  startovyj
adres programmy PZU, vypolnyayushchej preryvanie 8H. Na ris. 1-2 poka-
zana shema vypolneniya programmoj preryvaniya 21H.





   Dlya  upravleniya apparatnymi preryvaniyami vo vseh tipah IBM  PC
ispol'zuetsya mikroshema  programmiruemogo  kontrollera preryvanij
Intel 8259. Poskol'ku v kkazhdyj moment vremeni mozhet postupit' ne
odin zapros, mikroshema imeet shemu  prioritetov. Imeetsya 8 urov-
nej prioritetov, krome AT, u kotorogo ih 16, i obrashcheniya k  soot-
vetstvuyushchim urovnyam oboznachayutsya sokrashcheniyami ot IRQ0 do IRQ7 (ot
IRQ0 do IRQ15), chto oznachaet zapros na preryvanie.   Maksimal'nyj
prioritet sootvetstvuet urovnyu  0.   Dobavochnye  8 urovnej dlya AT
obrabatyvayutsya vtoroj mikroshemoj 8259; etot vtoroj nabor urovnej
imeet prioritet mezhdu IRQ2  i  IRQ3.  Zaprosy  na  preryvanie 0-7
sootvetstvuyut vektoram preryvanij ot 8H do 0FH; dlya AT zaprosy na
preryvaniya 8-15 obsluzhivayutsya vektorami  ot 70H do 77H. Nizhe pri-
vedeny naznacheniya etih preryvanij:

   Apparatnye preryvaniya v poryadke prioriteta.

   IRQ 0     tajmer
       1     klaviatura
       2     kanal vvoda/vyvoda
          8  chasy real'nogo vremeni (tol'ko AT)
          9  programmno perevodyatsya v IRQ2 (tol'ko AT)
         10  rezerv
         11  rezerv
         12  rezerv
         13  mat. soprocessor (tol'ko AT)
         14  kontroller fiksirovannogo diska (tol'ko AT)
         15  rezerv
       3     COM1 (COM2 dlya AT)
       4     COM2 (modem dlya PCjr, COM1 dlya AT)
       5     fiksirovannyj disk (LPT2 dlya AT)
       6     kontroller disket
       7     LPT1

   Preryvaniyu  vremeni sutok [2.1.0] dan maksimal'nyj  prioritet,
poskol'ku esli ono budet  postoyanno  teryat'sya, to budut nevernymi
pokazaniya sistemnyh chasov. Preryvanie ot klaviatury [3.1.0] vyzy-
vaetsya pri  nazhatii  ili  otpuskanii  klavishi;  ono vyzyvaet cep'
sobytij,  kotoraya obychno zakanchivaetsya tem, chto kod klavishi pome-
shchaetsya v bufer  klaviatury  (otkuda  on  zatem mozhet byt' poluchen
programmnymi preryvaniyami).
   Mikroshema 8259 imeet tri odnobajtnyh registra, kotorye uprav-
lyayut vosem'yu liniyami apparatnyh  preryvanij.   Registr zaprosa na
preryvanie  (IRR)  ustanavlivaet sootvetstvuyushchij bit, kogda liniya
preryvaniya signaliziruet o zaprose. Zatem mikroshema avtomatiches-
ki proveryaet ne obrabatyvaetsya li drugoe preryvanie. Pri etom ona
zaprashivaet informaciyu registra obsluzhivaniya  (ISR). Dopolnitel'-
naya  cep' otvechaet za shemu prioritetov.  Nakonec, pered  vyzovom
preryvaniya,  proveryaetsya  registr  maski  preryvanij (IMR), chtoby
uznat'  razresheno li v dannyj moment preryvanie  dannogo  urovnya.
Kak pravilo programmisty  obrashchayutsya tol'ko k registru maski pre-
ryvanij  cherez port 21H [1.2.2] i komandnomu registru  preryvanij
cherez port 20H [1.2.3].





   Programmy na aasemblere mogut zapretit' apparatnye preryvaniya,
perechislennye v [1.2.1]. |to maskiruemye preryvaniya; drugie appa-
ratnye preryvaniya, voznikayushchie  pri  nekotoryh oshibkah (takih kak
delenie  na nol') ne mogut byt' maskirovany.  Imeyutsya dve prichiny
dlya zapreta apparatnyh preryvanij. V pervom sluchae vse preryvaniya
blokiruyutsya  s  tem chtoby kriticheskaya chast' koda  byla  vypolnena
celikom, prezhde chem mashina proizvedet kakoe-libo drugoe dejstvie.
Naprimer, preryvaniya zapreshchayut pri izmenenii vektora  apparatnogo
preryvaniya, izbegaya  vypolneniya  preryvaniya  kogda vektor izmenen
tol'ko napolovinu.
   Vo  vtorom  sluchae maskiruyutsya tol'ko opredelennye  apparatnye
preryvaniya.  |to delaetsya kogda nekotorye opredelennye preryvaniya
mogut  vzaimodejstvovat'  s  operaciyami,  kritichnymi k  vremenam.
Naprimer, tochno rasschitannaya po vremeni procedura vvoda/vyvoda ne
mozhet sebe pozvolit' byt' prervannoj dlitel'nym diskovym preryva-
niem.

   Nizkij uroven'.

   Vypolnenie preryvanij  zavisit  ot  znacheniya  flaga preryvaniya
(bit 9) v registre flagov.  Kogda etot bit raven 0, to  razresheny
vse preryvaniya, kotorye razreshaet maska. Kogda on raven 1, to vse
apparatnye  preryvaniya  zapreshcheny.  CHtoby  zapretit'  preryvaniya,
ustanoviv etot flag v 1, ispol'zuetsya instrukciya CLI. Dlya ochistki
etogo  flaga i vosstanovleniya preryvanij - instrukciya STI.  Izbe-
gajte otklyucheniya preryvanij  na   dlitel'nyj  period.  Preryvanie
vremeni  sutok proishodit 18.2 raza v sekundu i esli k etomu pre-
ryvaniyu byl bolee chem odin  zapros  v  to vremya, kogda apparatnye
preryvaniya  byli zapreshcheny, to lishnie zaprosy budut  otbrosheny  i
sistemnoe vremya budet opredelyat'sya nepravil'no.
   Imejte vvidu, chto  mashina  avtomaticheski  zapreshchaet apparatnye
preryvaniya  pri  vyzove  programmnyh  preryvanij i  avtomaticheski
razreshaet ih pri vozvrate.  Kogda Vy pishete svoi programmnye pre-
ryvaniya,  to Vy mozhete nachat' programmu s instrukcii STI, esli Vy
mozhete dopustit' apparatnye  preryvaniya.  Otmetim takzhe, chto esli
za  instrukciej  CLI ne sleduet STI, to eto privedet k  ostanovke
mashiny, tak kak vvod s klaviatury budet zamorozhen.
   Dlya  maskirovaniya  opredelennyh  apparatnyh  preryvanij  nuzhno
prosto  poslat'  trebuemuyu cepochku bitov v  port s  adresom  21H,
kotoryj sootvetstvuet registru  maski  preryvanij (IMR).  Registr
maski  na  vtoroj  mikrosheme 8259 dlya AT (IRQ8-15)  imeet  adres
porta A1H.  Ustanovite te  bity  registra,  kotorye sootvetstvuyut
nomeram preryvanij, kotorye Vy hotite maskirovat'.  |tot  registr
mozhno tol'ko zapisyvat'.  Nizheprivedennyj primer blokiruet disko-
voe preryvanie.  Ne zabud'te ochistit' registr v konce  programmy,
inache obrashchenie k diskam budet zapreshcheno i posle zaversheniya prog-
rammy.

;---maskirovanie 6-go bita registra maski preryvanij
   MOV   AL,01000000B   ;maskiruem bit 6
   OUT   21H,AL         ;posylaem v registr maski preryvanij
    .
   MOV   AL,0           ;
   OUT   21H,AL         ;ochishchaem IMR v konce programmy





   Imeetsya  neskol'ko prichin dlya napisaniya sobstvennogo  preryva-
niya. Vo-pervyh, bol'shinstvo iz gotovyh preryvanij, obespechivaemyh
operacionnoj sistemoj, nichto inoe, kak obychnye procedury, dostup-
nye dlya vseh programm, i Vy  mozhete  pozhelat' dobavit' svoe v etu
biblioteku.   Naprimer, mnogie Vashi programmy mogut  ispol'zovat'
proceduru, vyvodyashchuyu stroki na  ekran  vertikal'no.  Vmesto togo,
chtoby  vklyuchat'  ee  v kazhduyu programmu v kachestve  procedury  Vy
mozhete ustanovit' ee kak  preryvanie,  napisav programmu, kotoraya
ostanetsya rezidentnoj v pamyati posle zaversheniya [1.3.4]. Togda Vy
mozhete ispol'zovat' INT 80H  vmesto WRITE_VERTICALLY (imejte vvi-
du,  chto vyzov preryvaniya neskol'ko medlennej, chem vyzov procedu-
ry).
   Vtoroj prichinoj napisaniya preryvaniya  mozhet byt' ispol'zovanie
kakogo-libo  otdel'nogo  apparatnogo preryvaniya.  |to  preryvanie
avtomaticheski vyzyvaetsya pri vozniknovenii  opredelennyh uslovij.
V  nekotoryh sluchayah BIOS inicializiruet vektor etogo  preryvaniya
tak, chto on ukazyvaet  na  proceduru,  kotoraya  voobshche  nichego ne
delaet (ona soderzhit odin operator IRET). Vy mozhete napisat' svoyu
proceduru i izmenit' vektor preryvanij, chtoby on ukazyval na nee.
Togda pri vozniknovenii apparatnogo preryvaniya budet  vypolnyat'sya
Vasha  procedura.   Odna iz takih procedur eto preryvanie  vremeni
sutok [2.1.0], kotoroe  avtomaticheski  vyzyvaetsya 18.2 raza v se-
kundu. Obychno eto preryvanie tol'ko obnovlyaet pokazanie chasov, no
Vy mozhete dobavit' k nemu lyuboj kod,  kotoryj Vy pozhelaete.  Esli
Vash kod proveryaet pokazaniya chasov i vstupaet v igru v  opredelen-
nye momenty vremeni,  to  vozmozhny  operacii  v real'nom vremeni.
Drugie vozmozhnosti - eto napisanie procedur obrabotki  Ctrl-Break
[3.2.8], PrtSC  [3.2.9]   i   vozniknoveniya   oshibochnyh  situacij
[7.2.5].  Preryvaniya printera [6.3.1] i kommunikacionnye  [7.1.8]
pozvolyayut komp'yuteru bystro  pereklyuchat'sya  mezhdu operaciyami vvo-
da/vyvoda i drugoj obrabotkoj.
   Nakonec, Vy mozhete zahotet' napisat' preryvanie, kotoroe  pol-
nost'yu zamenit odnu iz procedur  operacionnoj sistemy, prisposob-
lennoe k Vashim programmnym nuzhdam.  V [1.2.4] pokazano kak  napi-
sat' preryvanie vnutri  preryvaniya, kotoroe pozvolyaet Vam modifi-
cirovat' sushchestvuyushchie procedury.

   Srednij uroven'.

   Funkciya  25H preryvaniya 21H ustanavlivaet vektor preryvaniya na
ukazannyj adres.  Adresa imeyut  razmer  dva slova.  Starshee slovo
soderzhit  znachenie segmenta (CS), mladshee soderzhit smeshchenie (IP).
CHtoby ustanovit' vektor,  ukazyvayushchim  na odnu iz Vashih procedur,
nuzhno  pomestit' segment procedury v DS, a smeshchenie v DX  (sleduya
poryadku nizheprivedennogo primera). Zatem pomestite nomer preryva-
niya  v AL i vyzovite funkciyu.  Lyubaya procedura preryvaniya  dolzhna
zavershat'sya ne obychnoj instrukciej RET, a IRET. (IRET vytalkivaet
iz steka tri slova,  vklyuchaya  registr  flagov, v to vremya kak RET
pomeshchaet  na  stek tol'ko dva.  Esli Vy  popytaetes'  testirovat'
takuyu proceduru kak obychnuyu proceduru, no konchayushchuyusya IRET, to Vy
ischerpaete  stek.) Otmetim, chto funkciya 25H avtomaticheski  zapre-
shchaet apparatnye preryvaniya v processe  izmeneniya vektora, poetomu
ne sushchestvuet opasnosti, chto posredi dorogi proizojdet apparatnoe
preryvanie, ispol'zuyushchee dannyj vektor.


;---ustanovka preryvaniya
   PUSH  DS             ;sohranyaem DS
   MOV   DX,OFFSET ROUT ;smeshchenie dlya procedury v DX
   MOV   AX,SEG ROUT    ;segment procedury
   MOV   DS,AX          ;pomeshchaem v DS
   MOV   AH,25H         ;funkciya ustanovki vektora
   MOV   AL,60H         ;nomer vektora
   INT   21H            ;menyaem preryvanie
   POP   DS             ;vosstanavlivaem DS

;---procedura preryvaniya
ROUT  PROC  FAR
      PUSH  AX          ;sohranyaem vse izmenyaemye registry
       .
       .
      POP   AX          ;vosstanavlivaem registry
      MOV   AL,20H      ;eti dve stroki nado ispol'zovat'
      OUT   20H,AL      ;tol'ko dlya apparatnyh preryvanij
      IRET
ROUT  ENDP

   V konce koda kazhdogo iz Vashih apparatnyh  preryvanij Vy dolzhny
vklyuchit' sleduyushchie 2 strochki koda:

         MOV   AL,20H
         OUT   20H,AL

   |to  prosto sovpadenie, chto chisla (20H) odni i te  zhe v  obeih
strokah. Esli apparatnoe  preryvanie ne zakanchivaetsya etimi stro-
kami,  to mikroshema 8259 ne ochistit informaciyu registra obsluzhi-
vaniya, s tem chtoby byla  razreshena  obrabotka  preryvanij s bolee
nizkimi  urovnyami, chem tol'ko chto obrabotannoe.  Otsutstvie  etih
strok legko mozhet privesti k  krahu programmy, tak kak preryvaniya
ot   klaviatury   skoree  vsego  okazhutsya  zamorozhennymi i   dazhe
Ctrl-Alt-Del okazhetsya  bespoleznym.  Otmetim,  chto eta dobavka ne
nuzhna dlya teh vektorov preryvanij, kotorye yavlyayutsya  rasshireniyami
sushchestvuyushchih preryvanij, takim kak preryvanie 1CH, kotoroe dobav-
lyaet kod k preryvaniyu vremeni sutok [2.1.7].
   Kogda programma zavershaetsya, dolzhny byt' vosstanovleny  origi-
nal'nye vektora preryvanij. V  protivnom sluchae posleduyushchaya prog-
ramma mozhet vyzvat' dannoe preryvanie i peredat' upravlenie na to
mesto v pamyati, v kotorom  Vashej  procedury  uzhe net.  Funkciya 35
preryvaniya  21H vozvrashchaet tekushchee znachenie  vektora  preryvaniya,
pomeshchaya znachenie segmenta v ES, a smeshchenie v BX. Pered ustanovkoj
svoego  preryvaniya  poluchite tekushchee znachenie vektora,  ispol'zuya
etu funkciyu, sohranite eti  znacheniya,  i  zatem vosstanovite ih s
pomoshch'yu funkcii 25H (kak vyshe) pered zaversheniem svoej programmy.
Naprimer:

;---v segmente dannyh:
   KEEP_CS  DW    0        ;hranit segment zamenyaemogo preryvaniya
   KEEP_IP  DW    0        ;hranit smeshchenie preryvaniya
;---v nachale programmy
            MOV   AH,25H     ;funkciya polucheniya vektora
            MOV   AL,1CH     ;nomer vektora
            INT   21H        ;teper' segment v ES, smeshchenie v BX
            MOV   KEEP_IP,BX ;zapominaem smeshchenie
            MOV   KEEP_CS,ES ;zapominaem segment


; ---v konce programmy
            CLI
            PUSH  DS         ;DS budet razrushen
            MOV   DX,KEEP_IP ;podgotovka k vosstanovleniyu
            MOV   AX,KEEP_CS ;
            MOV   DS,AX      ;podgotovka k vosstanovleniyu
            MOV   AH,25H     ;funkciya ustanovki vektora
            MOV   AL,1CH     ;nomer vektora
            INT   21H        ;vosstanavlivaem vektor
            POP   DS         ;vosstanavlivaem DS
            STI

   Imeetsya  para lovushek, kotoryh sleduet izbegat' pri  napisanii
preryvaniya. Esli novaya procedura preryvaniya dolzhna imet' dostup k
dannym,  to neobhodimo pozabotit'sya, chtoby DS byl pravil'no usta-
novlen (obychno  preryvanie  mozhet  ispol'zovat'  stek  vyzyvayushchej
programmy).  Drugaya nepriyatnost' mozhet zaklyuchat'sya v tom, chto pri
zavershenii programmy  po  Ctrl-Break  vektor  preryvaniya ne budet
vosstanovlen,  esli tol'ko Vy ne predusmotrite,  chtoby  programma
reakcii na Ctrl-Break vypolnyala etu proceduru [3.2.8].

   Nizkij uroven'.

   Opisannye vyshe funkcii MS  DOS  prosto  poluchayut  ili izmenyayut
paru  slov v mladshih yachejkah pamyati.  Smeshchenie vektora mozhet byt'
vychisleno prostym umnozheniem nomera vektora na 4. Naprimer, chtoby
poluchit' adres preryvaniya 16H v ES:BX:

;---poluchenie adresa preryvaniya 16H
   SUB   AX,AX         ;ustanavlivaem ES na nachalo pamyati
   MOV   ES,AX         ;
   MOV   DI,16H        ;nomer preryvaniya v DI
   SHL   DI,1          ;umnozhaem na 2
   SHL   DI,1          ;umnozhaem na 2
   MOV   BX,ES:[DI]    ;berem mladshij bajt v BX
   MOV   AX,ES:[DI]+2  ;berem starshij bajt v ES
   MOV   ES,AX         ;

   Ne rekomenduetsya pryamo ustanavlivat' vektor preryvanij, obhodya
funkciyu DOS.  V chastnosti v mnogozadachnoj srede operacionnaya sis-
tema  mozhet  podderzhivat' neskol'ko tablic vektorov preryvanij  i
real'nyj fizicheskij adres tablicy mozhet byt' izvesten tol'ko DOS.





   Hotya i ne chasto, no inogda  byvaet  polezno dobavit' kod k su-
shchestvuyushchemu preryvaniyu.  V kachestve primera rassmotrim programmy,
kotorye preobrazuyut odno  nazhatie  klavishi v dlinnye opredelyaemye
pol'zovatelem  simvol'nye  stroki (makroopredeleniya  klaviatury).
|ti programmy ispol'zuyut fakt, chto  ves' vvod s klaviatury postu-
paet  postupaet cherez funkciyu 0 preryvaniya 16H BIOS [3.1.3].  Vse
preryvaniya vvoda s klaviatury  DOS  vyzyvayut  preryvanie BIOS dlya
polucheniya simvola iz bufera klaviatury.  Poetomu neobhodimo modi-
ficirovat' lish' preryvanie 16H,  takim obrazom, chtoby ono sluzhilo
shlagbaumom dlya makroopredelenij, posle chego lyubaya programma budet
poluchat' makroopredeleniya,  nezavisimo  ot togo, kakoe preryvanie
vvoda s klaviatury ona ispol'zuet.
   Konechno,  modificirovat' preryvaniya BIOS i DOS neprosto,  pos-
kol'ku BIOS raspolozhena v PZU, a DOS postupaet bez listinga i oni
ogranicheny  razmerami  otvedennoj dlya nih pamyati.  No  Vy  mozhete
napisat' proceduru, kotoraya  predshestvuet  i/ili sleduet za soot-
vetstvuyushchim  preryvaniem,  i eta procedura mozhet  vyzyvat'sya  pri
vyzove preryvaniya DOS  ili  BIOS.  Naprimer,  v sluchae preryvaniya
16H,  Vam nuzhno napisat' proceduru i ukazat' na nee vektorom pre-
ryvaniya dlya 16H.  Original'noe  znachenie vektora 16H tem vremenem
perenositsya  v  kakoj-libo  neispol'zuemyj vektor,  skazhem,  60H.
Novaya procedura prosto vyzyvaet  preryvanie  60H, chtoby ispol'zo-
vat'  original'noe preryvanie 16H; poetomu kogda programma  vyzy-
vaet preryvanie 16H, upravlenie peredaetsya Vashej procedure, koto-
raya zatem vyzyvaet original'noe preryvanie 16H, kotoraya po zaver-
shenii opyat' vozvrashchaet  upravlenie  Vashej procedure, a iz nee uzhe
Vy  vozvrashchaetes'  v to mesto programmy, iz  kotorogo  byl  vyzov
preryvaniya 16H. Posle togo  kak  eto  sdelano,  v novoj procedure
mozhet soderzhat'sya lyuboj kod, kak do, tak i posle vyzova  preryva-
niya 60H. Na ris. 1-3 pokazana diagramma etoj procedury. Vot krat-
kaya svodka neobhodimyh dejstvij:

   1. Sozdat' novuyu proceduru, vyzyvayushchuyu preryvanie 60H.
   2. Perenesti vektor preryvaniya dlya 16H v 60H.
   3. Izmenit' vektor 16H, chtoby on ukazyval na novuyu proceduru.
   4. Zavershit' programmu, ostavlyaya ee rezidentnoj [1.3.4].





   Bol'shinstvo  programm  zagruzhayutsya  v pamyat',  zapuskayutsya,  a
zatem udalyayutsya operacionnoj sistemoj pri zavershenii. YAzyki vyso-
kogo urovnya obychno ne imeyut al'ternativy. No dlya programmistov na
assemblere imeetsya drugaya  vozmozhnost' i dannyj razdel demonstri-
ruet  ee.   Nekotorye programmy dejstvuyut kak drajvery  ustrojstv
ili drajvery preryvanij i  oni  dolzhny  byt'  sohraneny  v pamyati
("rezidentnymi")  dazhe  posle ih zaversheniya  (vektora  preryvanij
obespechivayut mehanizm, posredstvom kotorogo posleduyushchie programmy
mogut  obrashchat'sya  k rezidentnym proceduram).   Inogda  programme
neobhodimo zapustit' iz sebya druguyu programmu.  Na samom dele DOS
pozvolyaet programme zagruzit' v pamyat' vtoruyu kopiyu  COMMAND.COM,
kotoraya mozhet ispol'zovana kak  sredstvo interfejsa s pol'zovate-
lem ili vypolneniya komand tipa COPY ili DIR.
   Programmy mogut byt' v dvuh formatah: .EXE ili .COM. Programmy
pervogo tipa mogut  byt'  bol'she  64K,  no  oni trebuyut nekotoroj
obrabotki pered tem, kak DOS zagruzit ih v pamyat'.  S drugoj sto-
rony COM programmy sushchestvuyut pryamo  v tom formate, kotoryj nuzhen
dlya zagruzki v pamyat'.  COM programmy osobenno polezny dlya korot-
kih utilit. V oboih sluchayah  kod, sostavlyayushchij programmu, predva-
ryaetsya  v pamyati prefiksom programmnogo segmenta (PSP).  |to  ob-
last' razmerom 100H bajt, kotoraya soderzhit informaciyu neobhodimuyu
DOS dlya raboty programmy; PSP takzhe obespechivaet mesto dlya fajlo-
vyh operacij vvoda/vyvoda [5.3.5].  Pri zagruzke EXE fajla i DS i
ES ukazyvayut na PSP. Dlya COM fajlov CS takzhe snachala ukazyvaet na
PSP.   Otmetim, chto MS DOS 3.0 imeet funkciyu, kotoraya  vozvrashchaet
nomer segmenta PSP. |to funkciya  62H preryvaniya 21H; ej nichego ne
nado podavat' na vhode, a v BX vozvrashchaetsya nomer paragrafa.
   Odna  iz prichin, po kotoroj interesno polozhenie PSP, sostoit v
tom, chto ego pervoe slovo soderzhit nomer preryvaniya DOS,  kotoroe
budet privodit' k zaversheniyu programmy. Kogda vypolnyaetsya posled-
nij  operator RET programmy, to znacheniya na vershine steka  ukazy-
vayut schetchiku komand  (registr  IP)  na nachalo PSP, takim obrazom
kod  zaversheniya  vypolnyaetsya kak sleduyushchaya instrukciya  programmy.
Dal'nejshee obsuzhdenie etogo smotrite v punktah [1.3.4] i [1.3.6].

   Dlya spravki privodim znachenie polej PSP:

   Smeshchenie  Razmer polya        Znachenie
     0H       DW           nomer funkcii DOS zaversheniya programmy
     2H       DW           razmer pamyati v paragrafah
     4H       DW           rezerv
     6H       DD           dlinnyj vyzov funkcii dispatchera DOS
     AH       DD           adres zaversheniya (IP,CS)
     EH       DD           adres vyhoda po Ctrl-Break (IP,CS)
    12H       DD           adres vyhoda po kriticheskoj oshibke
    16H     22 bajta       rezerv
    2CH       DW           nomer paragrafa stroki sredy
    2EH     46 bajtov      rezerv
    5CH     16 bajtov      oblast' parametrov 1 (format FCB)
    6CH     20 bajtov      oblast' parametrov 2 (format FCB)
    80H    128 bajtov      oblast' DTA po umolchaniyu/poluchaet
                           komandnuyu stroku programmy





   Kogda MS DOS zagruzhaet  programmu, to ona pomeshchaetsya v mladshuyu
oblast'  pamyati, srazu zhe za COMMAND.COM i ustanovlennymi drajve-
rami ustrojstv ili drugimi utilitami,  kotorye rezidentny v pamya-
ti.  V etot moment vremeni vsya pamyat' za programmoj otvedena etoj
programme. Esli programme nuzhna  pamyat' dlya sozdaniya oblasti dan-
nyh, to ona mozhet priblizhenno vychislit' gde v pamyati konchaetsya ee
kod i zatem pomestit' trebuemuyu  oblast'  dannyh v lyuboe mesto za
koncom  koda.  Dlya opredeleniya adresa konca programmy pomestite v
konce programmy psevdosegment tipa:

   ZSEG    SEGMENT
           ;
   ZSEG    ENDS

   V assemblere IBM PC ZSEG  budet  poslednim  segmentom, tak kak
segmenty raspolagayutsya v alfavitnom poryadke.  S drugimi assemble-
rami nuzhno dejstvitel'no  pomestit' eti stroki v konce programmy.
V samoj programme dostatochno  postavit' operator MOV AX,ZSEG i AX
budet ukazyvat' na pervyj svobodnyj segment pamyati za programmoj.
   Takoj  podhod  budet  rabotat' do teh por, poka  programma  ne
budet predpolagat' o nalichii  pamyati,  kotoroj na samom dele net.
On  ne budet takzhe rabotat' v mnogopol'zovatel'skoj srede,  kogda
neskol'ko programm mogut delit'  mezhdu soboj odnu i tu zhe oblast'
adresov.  Dlya resheniya etoj problemy MS DOS imeet vozmozhnost' ots-
lezhivat' 640K sistemnoj pamyati i otvodit' po trebovaniyu programmy
bloki pamyati lyubogo razmera. Blok pamyati - eto prosto nepreryvnaya
oblast' pamyati,  ego  maksimal'nyj  razmer  opredelyaetsya razmerom
dostupnoj  pamyati, v chastnosti, on mozhet byt' bol'she odnogo  seg-
menta (64K). Esli zatrebovan  slishkom bol'shoj blok, to DOS vydaet
soobshchenie ob oshibke. Lyubaya vozmozhnost' perekrytiya blokov isklyuche-
na. Krome togo MS DOS  mozhet  osvobozhdat',  urezat' ili rasshiryat'
sushchestvuyushchie  bloki.  Hotya programma ne obyazana ispol'zovat'  eti
sredstva, no udobno  i  predusmotritel'no  delat'  eto. Nekotorye
funkcii DOS trebuyut, chtoby byli ispol'zovany sredstva  upravleniya
pamyat'yu DOS, naprimer,  zavershenie  rezidentnoj programmy [1.3.4]
ili vyzov drugoj programmy iz dannoj [1.3.2].
   Prezhde  chem otvesti pamyat', sushchestvuyushchij blok (vsya  pamyat'  ot
nachala programmy do konca)  dolzhen  byt' obrezan do razmera prog-
rammy.  Zatem, pri sozdanii bloka, DOS sozdaet 16-bajtnyj  uprav-
lyayushchij blok  pamyati,  kotoryj  raspolozhen  neposredstvenno  pered
blokom pamyati. Pervye 5 bajtov etogo bloka imeyut sleduyushchee znache-
nie:

   bajt 0     ASCII 90 - esli poslednij blok v cepochke, inache
              ASCII 77.
   bajty 1-2  0 esli blok osvobozhden
   bajty 3-4  razmer bloka v 16-bajtnyh paragrafah

   DOS obrashchaetsya k blokam po cepochke.   Adres pervogo bloka hra-
nitsya  vo vnutrennej peremennoj.  Znachenie etoj peremennoj pozvo-
lyaet DOS opredelit'  polozhenie  pervogo  otvedennogo  bloka, a iz
informacii,  soderzhashchejsya v nem, mozhet byt' najden sleduyushchij blok


i t.d., kak pokazano na ris.  1-4. Kak tol'ko Vy nachali ispol'zo-
vat'  sistemu  raspredeleniya pamyati DOS, to Vy obyazany  priderzhi-
vat'sya ee.  Esli programma izmenit soderzhimoe upravlyayushchego bloka,
to  cepochka  budet razorvana i DOS nachnet vydavat'  soobshcheniya  ob
oshibke.
   MS DOS obespechivaet tri  funkcii  raspredeleniya pamyati, nomera
ot 48H do 4AH preryvaniya 21H.  Funkciya 48H otvodit blok pamyati, a
49H - osvobozhdaet blok pamyati.   Tret'ya  funkciya ("SETBLOCK") me-
nyaet  razmer pamyati, otvedennoj dlya programmy; eta funkciya dolzhna
byt' ispol'zovana pered  dvumya  ostal'nymi.  Posle  ee vypolneniya
mozhno  spokojno otvodit' i osvobozhdat' bloki  pamyati.   Programma
dolzhna  osvobodit'  vse  otvedennye  eyu  bloki pered zaversheniem.
Inache  eta pamyat' budet nedostupnoj dlya posleduyushchego  ispol'zova-
niya.

   Srednij uroven'.

   Vse tri funkcii raspredeleniya pamyati preryvaniya 21H ispol'zuyut
16-bitnyj  adres  nachala bloka pamyati, s kotorym  oni  operiruyut.
|tot adres  sootvetstvuet  segmentu,  s  kotorogo nachinaetsya blok
(blok  vsegda nachinaetsya so smeshcheniya 0 dannogo segmenta).   Takim
obrazom real'nyj adres  yachejki  nachala  bloka raven etomu adresu,
umnozhennomu  na  16.  Takzhe, dlya vseh treh funkcij,  BX  soderzhit
chislo 16-bajtnyh  razdelov  pamyati  (paragrafov),  kotorye  budut
otvodit'sya ili osvobozhdat'sya. Esli funkciya ne mozhet byt' vypolne-
na, to ustanavlivaetsya  flag  perenosa,  a  v AX vozvrashchaetsya kod
oshibki, ob®yasnyayushchij prichinu. Vozmozhny tri koda oshibki:

   7   razrushen upravlyayushchij blok pamyati
   8   nedostatochno pamyati dlya vypolneniya funkcii
   9   nevernyj adres bloka pamyati

Funkciya otvedeniya bloka ispol'zuet kody 7 i 8, a osvobozhdeniya - 7
i 9, v to vremya kak  funkciya  izmeneniya  bloka ispol'zuet vse tri
koda.  V sleduyushchem primere snachala otvoditsya blok, razmerom  1024
bajta. Pri etom BX soderzhit  trebuemoe  chislo 16-bajtnyh paragra-
fov,  a  pri zavershenii startovyj adres bloka  raven  AX:0  (t.e.
smeshchenie 0 v segmente so  znacheniem,  soderzhashchimsya v AX).  Vtoraya
chast'  primera osvobozhdaet etot zhe blok, kak i trebuetsya pri  za-
vershenii programmy.  V  dannom  sluchae  znachenie  poluchennoe v AX
pomeshchaetsya v ES. DOS sledit za razmerom bloka i znaet kakoe koli-
chestvo paragrafov nado osvobodit'.

;---otvedenie bloka razmerom 1024 bajta
   MOV   AH,48H      ;nomer funkcii
   MOV   BX,64       ;trebuem 64 paragrafa
   INT   21H         ;pytaemsya otvesti blok
   JC    ERROR       ;obrabatyvaem oshibku v sluchae neudachi
   MOV   BLOCK_SEG,AX;inache sohranyaem adres bloka
    .
;---osvobozhdaem tot zhe blok
   MOV   AX,BLOCK_SEG ;poluchaem startovyj adres bloka
   MOV   ES,AX        ;pomeshchaem ego v ES
   MOV   AH,49H       ;nomer trebuemoj funkcii
   INT   21H          ;osvobozhdaem blok pamyati


   Nakonec, privedem primer ispol'zovaniya funkcii 4AH.  ES soder-
zhit  znachenie segmenta PSP, t.e.  samogo pervogo bajta pamyati,  s
kotorogo zagruzhena programma.  |to  znachenie prisvaivaetsya ES pri
starte zadachi.  Dlya ispol'zovaniya SETBLOCK nado libo vyzyvat' etu
funkciyu v samom nachale  programmy  (prezhde chem ES budet izmenen),
libo sohranit' ego nachal'noe znachenie dlya posleduyushchego  ispol'zo-
vaniya.
   BX soderzhit trebuemyj  razmer  bloka  v 16-bajtnyh paragrafah.
Dlya opredeleniya etogo razmera pomestite dobavochnyj "iskustvennyj"
segment v konec programmy.  V  makroasssemblere  IBM  PC segmenty
raspolagayutsya  v alfavitnom poryadke, poetomu Vy mozhete  pomestit'
ego v lyuboe mesto programmy, pri uslovii,  chto ego imya eto chto-to
vrode  "ZSEG".  V drugih assemblerah dejstvitel'no pomeshchajte fik-
tivnyj segment v konec programmy. Programma mozhet prochitat' pozi-
ciyu etogo segmenta i, sravnivaya ee so startovym segmentom,  polu-
chit' kolichestvo pamyati, trebuemoe samoj programme.  V moment zag-
ruzki programmy i ES i DS soderzhat nomer paragrafa samogo  nachala
programmy v  prefikse  programmnogo  segmenta;  dlya COM fajlov CS
takzhe ukazyvaet na etu poziciyu, no dlya EXE fajlov eto ne tak.
;---osvobozhdenie pamyati (ES imeet znachenie pri starte)
   MOV   BX,ZSEG      ;poluchaem # paragrafa konca programmy + 1
   MOV   AX,ES        ;poluchaem # paragrafa nachala programmy
   SUB   BX,AX        ;vychislyaem razmer programmy v paragrafah
   MOV   AH,4AH       ;nomer funkcii
   INT   21H          ;osvobozhdaem pamyat'
   JC    MEMORY_ERROR ;proveryaem na oshibku

;---
   ZSEG      SEGMENT
   ZSEG      ENDS





   MS  DOS obespechivaet funkciyu EXEC (nomer 4BH preryvaniya  21H),
realizuyushchuyu vyzov odnoj  programmy  iz  drugoj.  Pervaya programma
nazyvaetsya "roditelem", a zagruzhaemaya i zapuskaemaya - "potomkom".

   Vysokij uroven'.

   V  Bejsik versii 3.0 vvedena komanda SHELL.  So  znachitel'nymi
ogranicheniyami ona  pozvolyaet  bejsikovskoj  programme zagruzit' i
vypolnit' druguyu programmu. Format etoj komandy SHELL kom_stroka.
Komandnaya stroka mozhet byt' prosto imenem programmy ili ona mozhet
soderzhat' krome imeni parametry, kotorye obychno sleduyut za imenem
programmy v  komandnoj  stroke.  Esli  kom_stroka  ne ukazana, to
zagruzhaetsya  kopiya  COMMAND.COM i poyavlyaetsya zapros  operacionnoj
sistemy. V etot moment mozhno vypolnit' lyubuyu komandu MS DOS, a po
zaversheniyu  vernut' upravlenie bejsikovskoj programme, vvedya  ko-
mandu EXIT.
   Imeetsya ryad ogranichenij pri  ispol'zovanii  SHELL. Esli zagru-
zhaemaya  programma  menyaet  rezhim raboty displeya, to on  ne  budet
avtomaticheski vosstanovlen pri vozvrate. Pered zagruzkoj program-
my vse fajly dolzhny byt' zakryty, i eto ne mozhet byt'  programma,
kotoraya ostaetsya rezidentnoj  posle  zaversheniya.  Obsuzhdenie ryada
drugih problem soderzhitsya v rukovodstve po Bejsiku.

   Srednij uroven'.

   Funkciya 4BH bolee slozhna, chem ostal'nye, trebuya chetyreh podgo-
tovitel'nyh shagov:

   1. Podgotovit' v pamyati mesto, dostupnoe programme.
   2. Sozdat' blok parametrov.
   3. Postroit' stroku,  soderzhashchuyu  nakopitel', put' i imya prog-
rammy.
   4. Sohranit' znacheniya registrov SS i SP v peremennyh.

   Poskol'ku  pri zagruzke programmy MS DOS vydelyaet ej vsyu  dos-
tupnuyu pamyat', to neobhodimo  osvobodit'  mesto v pamyati. Esli ne
osvobodit'  chast'  pamyati, to ne budet mesta dlya zagruzki  vtoroj
programmy.  V [1.3.1] ob®yasneno kak eto sdelat' s pomoshch'yu funkcii
SETBLOCK.   Posle  togo kak pamyat' osvobozhdena, Vy dolzhny  prosto
pomestit' v BX trebuemoe chislo 16-bajtnyh paragrafov, zaslat' 4AH
v AH i vypolnit' preryvanie 21H, delaya dostupnym programme imenno
to chislo paragrafov, kotoroe ej trebuetsya.
   Blok   parametrov,  na  kotoryj  dolzhny  ukazyvat'  ES:BX  eto
14-bajtnyj blok blok pamyati, v  kotoryj  Vy dolzhny pomestit' sle-
duyushchuyu informaciyu:

   DW   segmentnyj adres stroki sredy
   DD   segment i smeshchenie komandnoj stroki
   DD   segment i smeshchenie pervogo FCB
   DD   segment i smeshchenie vtorogo FCB


   Stroka sredy - eto stroka, sostoyashchaya iz odnoj ili bolee speci-
fikacij, kotorym sleduet MS DOS pri vypolnenii programmy. |lemen-
ty  stroki sredy takie zhe, kak i te chto mozhno obnaruzhit' v disko-
vom fajle  CONFIG.SYS.   Naprimer,  v  stroku mozhet byt' pomeshcheno
VERIFY  = ON.  Prosto nachnite stroku s pervogo elementa, zavershiv
ego simvolom ASCII 0, potom zapishite  sleduyushchij i t.d. Za posled-
nim elementom dolzhny sledovat' dva simvola ASCII 0. Stroka dolzhna
nachinat'sya na granice paragrafa (t.e.  ee adres po modulyu 16 dol-
zhen byt' raven nulyu). |to vyzvano tem, chto sootvetstvuyushchij vhod v
bloke parametrov, ukazyvayushchij na stroku,  soderzhit tol'ko 2-bajt-
noe  segmentnoe znachenie.  Vse eto ne nuzhno, esli novaya programma
mozhet rabotat' s toj  zhe  strokoj  sredy,  chto i programma "rodi-
tel'".  V etom sluchae nado prosto pomestit' dva simvola ASCII 0 v
pervye 2 bajta bloka parametrov.
   Sleduyushchie  4  bajta  bloka parametrov ukazyvayut  na  komandnuyu
stroku dlya zagruzhaemoj  programmy.  "Komandnaya stroka" - eto sim-
vol'naya stroka, opredelyayushchaya sposob raboty programmy. Pri zagruz-
ke programmy iz DOS ona mozhet imet' vid vrode EDITOR  A:CHAPTER1\
NOTES.MS. Pri etom vyzyvaetsya redaktor i emu peredaetsya imya fajla
v podkataloge nakopitelya A dlya  nemedlennogo  otkrytiya.  Kogda Vy
podgotavlivaete komandnuyu stroku dlya EXEC, to nado vklyuchat' tol'-
ko poslednyuyu chast' informacii,  no  ne imya zagruzhaemoj programmy.
Pered komandnoj strokoj dolzhen stoyat' bajt, soderzhashchij dlinu etoj
stroki, i ona dolzhna zavershat'sya simvolom <VK> (ASCII 13).
   Poslednie 8 bajtov bloka  parametrov  ukazyvayut na upravlyayushchie
bloki  fajlov (FCB).  FCB soderzhit informaciyu ob odnom  ili  dvuh
fajlah, ukazannyh v komandnoj  stroke.   Esli  otkryvaemyh fajlov
net,  to  nado zapolnit' vse 8 bajt simvolom ASCII 0.  V  [5.3.5]
ob®yasneno, kak rabotaet FCB. Nachinaya s versii MS DOS 2.0, ispol'-
zovanie FCB neobyazatel'no i Vy mozhete ne vklyuchat' informaciyu FCB,
vmesto etogo ispol'zuya novuyu  konvenciyu  deskriptora fajlov (file
handler),  v  kotoroj dostup k fajlu predostavlyaetsya po  kodovomu
nomeru, a ne cherez FCB (takzhe obsuzhdaetsya v [5.3.5]).
   Nakonec, Vy dolzhny postroit'  stroku  s  ukazaniem nakopitelya,
puti  i  imeni fajla.  |ta stroka imenuet zagruzhaemuyu  programmu.
DS:DX ukazyvaet na etu stroku  pri  vypolnenii EXEC. |ta stroka -
standartnaya  stroka ASCIIZ, t.e.  nichego bolee,  chem  standartnaya
specifikaciya  fajla,  zavershaemaya  kodom  ASCII 0.  Naprimer, eto
mozhet  byt' B:\NEWDATA\FILER.EXE<NUL>, gde simvolom <NUL> obozna-
chen kod ASCII 0.
   Posle togo kak vsya ukazannaya informaciya podgotovlena, ostaetsya
poslednyaya zadacha.  Poskol'ku vse registry budut izmeneny vyzyvae-
moj zadachej, to nado sohranit' segment steka i ukazatel' steka, s
tem  chtoby  oni mogli byt' vosstanovleny, kogda upravlenie  budet
vozvrashcheno vyzvavshej zadache.  Dlya ih sohraneniya sozdajte peremen-
nye.  Poskol'ku znachenie registra DS takzhe budet izmeneno, to eti
peremennye ne mogut byt' najdeny, do teh por poka ne budut povto-
reny operatory MOV AX,DSEG i  MOV  DS,AX.  Posle togo kak SS i SP
sohraneny,  pomestite  0  v AL, dlya vybora operacii  "zagruzka  i
zapusk" (EXEC  ispol'zuetsya  takzhe  dlya  overleev [1.3.5]). Zatem
pomestite 4AH v AH i vyzovite preryvanie 21H. V etot moment zapu-
shcheny dve programmy, prichem programma "roditel'" nahoditsya v osta-
novlennom sostoyanii.  MS DOS predostavlyaet vozmozhnost'  programme
potomku peredat' roditelyu kod  vozvrata, takim obrazom mogut byt'
peredany  oshibki i status.  V [7.2.5] ob®yasneno kak eto  sdelat'.
CHto kasaetsya samoj funkcii  zapuska,  to pri vozniknovenii oshibki
ustanavlivaetsya  flag perenosa, a registr AX v etom sluchae  budet
vozvrashchat' 1 - dlya nepravil'nogo nomera funkcii, 2 - esli fajl ne
najden,  5  - pri diskovoj oshibke, 8 - pri nehvatke pamyati, 10  -
esli nepravil'na stroka sredy i 11 - esli neveren format.


   Privodimyj primer - prostejshij  iz  vozmozhnyh, no chasto bol'she
nichego  i ne nado.  Zdes' ostavlen nulevym blok  parametrov i  ne
sozdana stroka sredy. |to  oznachaet, chto zagruzhaemoj programme ne
budet  peredavat'sya komandnaya stroka i chto sreda budet takoj  zhe,
kak i dlya vyzyvayushchej programmy. Vy dolzhny tol'ko izmenit' raspre-
delenie  pamyati, sozdat' imya i (pustoj) blok parametrov i  sohra-
nit' znacheniya SS i SP.

;---v segmente dannyh
FILENAME     DB   'A:TRIAL.EXE',0  ;zagruzhaem TRIAL.EXE
PARAMETERS   DW   7DUP(0)          ;nulevoj blok parametrov
KEEP_SS      DW   0                ;peremennaya dlya SS
KEEP_SP      DW   0                ;peremennaya dlya SP

;---pereraspredelenie pamyati
   MOV   BX,ZSEG          ;poluchit' # paragrafa konca
   MOV   AX,ES            ;poluchit' # paragrafa nachala
   SUB   BX,AX            ;vychislit' razmer programmy
   MOV   AH,4AH           ;nomer funkcii
   INT   21H              ;pereraspredelenie
;---ukazyvaem na blok parametrov
   MOV   AX,SEG PARAMETERS      ;v ES - segment
   MOV   ES,AX                  ;
   MOV   BX,OFFSET PARAMETERS   ;v BX - smeshchenie
;---sohranit' kopii SS i SP
   MOV   KEEP_SS,SS       ;sohranyaem SS
   MOV   KEEP_SP,SP       ;sohranyaem SP
;---ukazyvaem na stroku imeni fajla
   MOV   DX,OFFSET FILENAME     ;smeshchenie - v DX
   MOV   AX,SEG FILENAME        ;segment - v DS
   MOV   DS,AX                  ;
;---zagruzka programmy
   MOV   AH,4BH           ;funkciya EXEC
   MOV   AL,0             ;vybiraem "zagruzku i zapusk"
   INT   21H              ;zapuskaem zadachu
;---vposledstvii, vosstanavlivaem registry
   MOV   AX,DSEG          ;vosstanavlivaem DS
   MOV   DS,AX            ;
   MOV   SS,KEEP_SS       ;vosstanavlivaem SS
   MOV   SP,KEEP_SP       ;vosstanavlivaem SP

;---v konce programmy sozdaem fiktivnyj segment
ZSEG     SEGMENT          ;sm. [1.3.1]
ZSEG     ENDS





   Programma mozhet imet' v svoem rasporyazhenii polnyj nabor komand
interfejsa s pol'zovatelem DOS, takih  kak DIR ili CHKDSK.  Kogda
eti komandy ispol'zuyutsya iz programmy, zagruzhaetsya i  zapuskaetsya
vtoraya kopiyu  COMMAND.COM.  Hotya  takoj  podhod  mozhet sekonomit'
mnogo  usilij  pri programmirovanii, dlya ego uspeshnoj  realizacii
trebuetsya dostatochnoe  kolichestvo  pamyati dlya etoj vtoroj kopii i
Vasha programma mozhet popast' v lovushku esli pamyati nedostatochno.

   Vysokij uroven'.

   Bejsik  3.0 mozhet zagruzit' vtoruyu kopiyu COMMAND.COM s pomoshch'yu
operatora SHELL.  SHELL obsuzhdaetsya v [1.3.2]. COMMAND.COM zagru-
zhaetsya kogda ne ukazano imya fajla, poetomu vvodya prosto SHELL, Vy
poluchaete zapros MS DOS. V etot  moment  mozhno ispol'zovat' lyubuyu
iz utilit DOS, vklyuchaya komandnye fajly.  Dlya vozvrata v vyzvavshuyu
programmu nado vvesti EXIT.

   Srednij uroven'.

   V etom sluchae k primeru, privedennomu v [1.3.2] nuzhno dobavit'
komandnuyu  stroku.  Obychno ona nachinaetsya s bajta  dliny  stroki,
zatem sleduet sama komandnaya stroka i, nakonec, kod ASCII 13. Pri
peredache  komandy COMMAND.COM Vy dolzhny ukazat' /C pered  strokoj
(sm. punkt "Vyzov vtorichnogo  komandnogo  processora" rukovodstva
po MS DOS).  Vy dolzhny takzhe ukazat' nakopitel', na kotorom naho-
ditsya COMMAND.COM,  pomestiv  imya  nakopitelya  v nachale komandnoj
stroki.   CHtoby vyvesti katalog nakopitelya A:, a COMMAND.COM  pri
etom nahoditsya na nakopitele B:, nuzhna stroka:

   COMMAND_LINE   DB   12,'B: /C DIR A:',13

   Sleduyushchij  kusochek koda ustanavlivaet adres komandnoj stroki v
blok parametrov, ispol'zuemyj v primere [1.3.2]:

   LEA   BX,PARAMETERS            ;poluchenie adresa bloka par-rov
   MOV   AX,OFFSET COMMAND_LINE   ;poluchenie smeshcheniya kom. stroki
   MOV   [BX]+2,AX                ;peresylka v 1-e 2 bajta bloka
   MOV   AX,SEG COMMAND_LINE      ;poluchenie segmenta kom. stroki
   MOV   [BX]+4,AX                ;peresylka vo 2-e 2 bajta bloka





   Programmy, ostavlennye rezidentnymi  v pamyati, mogut sluzhit' v
kachestve utilit dlya drugih programm. Obychno takie programmy vyzy-
vayutsya cherez neispol'zuemyj vektor  preryvaniya. MS DOS rassmatri-
vaet  takie programmy kak chast' operacionnoj sistemy, zashchishchaya  ih
ot nalozheniya drugih programm, kotorye  budut zagruzheny vposledst-
vii. Rezidentnye programmy obychno pishutsya v forme COM, chto obsuzh-
daetsya v punkte [1.3.6].  Programmy, napisannye v forme EXE osta-
vit' rezidentnymi v pamyati nemnogo trudnee.
   Zavershenie  programmy preryvaniem 27H ostavlyaet ee rezidentnoj
v pamyati.  CS dolzhen ukazyvat'  na nachalo PSP dlya togo, chtoby eta
funkciya rabotala pravil'no. V programmah COM, CS srazu ustanavli-
vaetsya  sootvetstvuyushchim  obrazom,  poetomu  nado prosto zavershit'
programmu  preryvaniem 27H.  V programmah EXE , CS  pervonachal'no
ukazyvaet na pervyj bajt, sleduyushchij  za PSP (t.e. 100H). Pri nor-
mal'nom zavershenii EXE programmy poslednyaya instrukciya RET  vytal-
kivaet iz steka  pervye  polozhennye  tuda znacheniya: PUSH DX / MOV
AX,0  / PUSH AX.  Poskol'ku DS pervonachal'no ukazyvaet na  nachalo
PSP, to pri poluchenii etih znachenij  iz steka schetchik komand uka-
zyvaet  na smeshchenie 0 v PSP, gde pri  inicializacii  zapisyvaetsya
instrukciya INT 20H. Poetomu INT  20H vypolnyaetsya, a eto standart-
naya funkciya dlya zaversheniya programmy i peredachi upravleniya v DOS.
Na ris. 1-5 pokazan etot process.  CHtoby zastavit' preryvanie 27H
rabotat'  v EXE programme nado pomestit' 27H vo vtoroj  bajt  PSP
(pervyj soderzhit mashinnyj kod  instrukcii INT), a zatem zavershit'
programmu obychnym RET.  Dlya oboih tipov fajlov prezhde chem  vypol-
nit' preryvanie 27H, DX dolzhen  soderzhat' smeshchenie konca program-
my, otschityvaemoe ot nachala PSP.

   Srednij uroven'.

   Vektor preryvaniya ustanavlivaetsya s pomoshch'yu funkcii 25H prery-
vaniya 21H, kak  pokazano  v  [1.2.3]  (zdes'  ispol'zuetsya vektor
70H).   Pozabot'tes',  chtoby procedura okanchivalas' IRET.   Krome
samoj procedury, ustanavlivaemaya programma ne dolzhna delat' niche-
go, krome inicializacii vektora preryvaniya, prisvoeniya DX  znache-
niya smeshcheniya konca procedury i zaversheniya.  Dlya COM fajlov prosto
pomestite  operator  INT 27H v konec programmy.  Dlya  EXE  fajlov
pomestite etot operator v pervoe  slovo PSP i zavershite programmu
obychnym operatorom RET. Dlya togo chtoby vypolnit' proceduru, vpos-
ledstvii zagruzhennaya programma dolzhna vyzvat' INT 70H.
   Privedeny primery dlya oboih tipov fajlov (COM i EXE).  V oboih
ustanovlena  metka FINISH dlya otmetki konca procedury  preryvaniya
(napominaem, chto znak $  daet  znachenie  schetchika  komand  v etoj
tochke).  Dlya COM fajlov FINISH daet smeshchenie ot nachala PSP, kak i
trebuetsya dlya preryvaniya  27H.  Dlya  EXE fajlov smeshchenie otschity-
vaetsya  ot pervogo bajta, sleduyushchego za PSP, poetomu k nemu neob-
hodimo pribavit' 100H, chtoby pereschitat'  na nachalo PSP. Zametim,
chto  pomestiv  proceduru v nachalo programmy, my  mozhem  isklyuchit'
ustanovochnuyu chast' koda iz  rezidentnoj  porcii. Drugoj vozmozhnyj
fokus sostoit v ispol'zovanii instrukcii MOVSB dlya peresylki koda
procedury vniz v  neispol'zuemuyu  chast'  PSP, nachinaya so smeshcheniya
60H, chto osvobozhdaet 160 bajt pamyati.


   Sluchaj fajla COM:
;---zdes' procedura preryvaniya
BEGIN:     JMP   SHORT SET_UP  ;perehod na ustanovku
ROUTINE    PROC  FAR
           PUSH  DS            ;sohranenie registrov
            .
      (procedura)
            .
           POP   DS            ;vosstanovlenie registrov
           IRET                ;vozvrat iz preryvaniya
FINISH     EQU   $             ;otmetka konca procedury
ROUTINE    ENDP

;---ustanovka vektora preryvaniya
SET_UP:    MOV   DX,OFFSET ROUTINE  ;smeshchenie procedury v DX
           MOV   AL,70H             ;nomer vektora preryvaniya
           MOV   AH,25H             ;funkciya ustanovki vektora
           INT   21H                ;ustanavlivaem vektor
;---zavershenie programmy, ostavlyaya rezidentnoj
           LEA   DX,FINISH          ;opredelyaem treb. smeshchenie
           INT   27H                ;zavershenie

   Sluchaj fajla EXE:

;---zdes' rezidentnaya procedura
           JMP   SHORT SET_UP   ;perehod na ustanovku
ROUTINE    PROC  FAR
           PUSH  DS             ;sohranenie registrov
            .
       (procedura)
            .
           POP   DS             ;vosstanovlenie registrov
           IRET                 ;vozvrat iz preryvaniya
FINISH     EQU   $              ;otmetka konca procedury
ROUTINE    ENDP

;---ustanovka vektora preryvaniya
SET_UP:    MOV   DX,OFFSET ROUTINE  ;smeshchenie procedury v DX
           MOV   AX,SEG ROUTINE     ;segment procedury v DS
           MOV   DS,AX              ;
           MOV   AL,70H             ;nomer vektora preryvaniya
           MOV   AH,25H             ;funkciya ustanovki vektora
           INT   21H                ;ustanovka vektora
;---zavershenie programmy
           MOV   DX,FINISH+100H     ;vychislyaem smeshchenie konca
           MOV   BYTE PTR ES:1,27H  ;posylaem 27H v PSP
           RET                      ;zavershaem proceduru

   Funkciya 31H preryvaniya 21H rabotaet analogichno, za isklyucheniem
togo, chto v DX  dolzhno  soderzhat'sya  chislo 16-bajtnyh paragrafov,
trebuemyh  procedure  (vychislenie razmera procedury,  nachinaya  ot
nachala PSP - sm.  v primere [1.3.1]).  Preimushchestvom etoj funkcii
yavlyaetsya  to, chto ona peredaet roditel'skoj programme kod vyhoda,
dayushchij informaciyu o  statuse  procedury.  Roditel'skaya  programma
poluchaet  etot  kod s pomoshch'yu funkcii 4DH preryvaniya  21H.   Kody
vyhoda obsuzhdayutsya v [7.2.5].





   Overlei - eto chasti programmy, kotorye ostayutsya na diske, v to
vremya  kak  telo programmy rezidentno v pamyati.  Kogda  trebuetsya
funkciya,  vypolnyaemaya  kakim-libo  overleem,  to on zagruzhaetsya v
pamyat' i programma vyzyvaet ego kak proceduru.  Razlichnye overlei
mogut zagruzhat'sya v odno i to zhe mesto  pamyati, perekryvaya predy-
dushchij  kod.  Naprimer, programma vedeniya bazy dannyh mozhet zagru-
zit' proceduru sortirovki, a zatem  perekryt' ee proceduroj gene-
racii otchetov.  |ta tehnika ispol'zuetsya dlya ekonomii pamyati.  No
ona horosha tol'ko dlya teh procedur,  kotorye ne ispol'zuyutsya pos-
toyanno, inache chastye obrashcheniya k disku privedut k tomu, chto prog-
ramma budet vypolnyat'sya slishkom medlenno.

   Srednij uroven'.

   MS DOS ispol'zuet  funkciyu  EXEC  dlya  zagruzki  overleev. |ta
funkciya, nomer 4BH preryvaniya 21H, ispol'zuetsya takzhe dlya zagruz-
ki i zapuska odnoj programmy iz  drugoj,  esli  pomestit' kod 0 v
AL  [1.3.2].  Esli v AL pomestit' kod 3, to togda budet  zagruzhen
overlej. V etom sluchae ne sozdaetsya PSP, poetomu overlej ne usta-
navlivaetsya  kak nezavisimaya programma.  Takaya  procedura  prosto
zagruzhaet overlej, ne peredavaya emu upravleniya.
   Imeetsya dva sposoba obespechit' pamyat' dlya overleya.  Mozhet byt'
ispol'zovana libo oblast' vnutri tela programmy, libo  special'no
otvedena oblast' pamyati za predelami golovnoj programmy.  Funkcii
EXEC peredaetsya tol'ko segmentnyj adres, v kachestve pozicii, kuda
budet zagruzhen overlej. Kogda overlej zagruzhaetsya v telo golovnoj
programmy,  to programma dolzhna vychislit' nomer  paragrafa,  kuda
budet zagruzhat'sya overlej, sama. S drugoj storony, pri zagruzke v
special'no otvedennuyu pamyat' MS DOS obespechivaet programmu  nome-
rom paragrafa.
   V nizheprivedennom primere  ispol'zuetsya  zagruzka v otvedennuyu
pamyat'.  Poskol'ku DOS otvodit programme vsyu dostupnuyu pamyat', to
snachala neobhodimo osvobodit' pamyat' s pomoshch'yu funkcii 4AH. Funk-
ciya  48H  otvodit  blok pamyati dostatochno bol'shoj, chtoby  on  mog
prinyat' samyj bol'shoj iz overleev.  |ta funkciya vozvrashchaet znache-
nie  segmenta bloka v AX, i etot nomer paragrafa opredelyaet  kuda
budet zagruzhen overlej, a takzhe  po  kakomu  adresu overlej budet
vyzyvat'sya golovnoj programmoj.  |ti funkcii detal'no obsuzhdayutsya
v [1.3.1].
   Krome koda 3, zasylaemogo v  AL, Vy dolzhny ustanovit' dlya etoj
funkcii eshche dva parametra. DS:DX dolzhny ukazyvat' na stroku, dayu-
shchuyu put' k fajlu overleya, zavershaemuyu bajtom ASCII 0.  Neobhodimo
ukazyvat'  polnoe  imya  fajla,  vklyuchaya rasshirenie .COM ili .EXE,
poskol'ku DOS v dannom sluchae ne schitaet, chto on ishchet programmnyj
fajl.
   Nakonec,  ES:BX dolzhny ukazyvat' na 4-bajtnyj blok parametrov,
kotoryj soderzhit (1) 2-bajtnyj nomer paragrafa, kuda budet zagru-
zhat'sya  overlej  i (2) 2-bajtnyj faktor privyazki,  kotoryj  budet
ispol'zovat'sya dlya privyazki  adresov  v  overlee (privyazka ob®yas-
nyaetsya v [1.3.6]).  V kachestve nomera paragrafa nado ispol'zovat'
chislo,  vozvrashchaemoe v AX, dlya nomera paragrafa otvedennogo bloka
pamyati.  Faktor privyazki  daet  smeshchenie,  po kotoromu mogut byt'
vychisleny adresa trebuyushchih privyazki parametrov v overlee. Ispol'-


zujte nomer paragrafa, kuda zagruzhaetsya  overlej.  Posle togo kak
on ustanovlen, vyzovite funkciyu i overlej budet zagruzhen.  Prosto
izmenyaya put' k  overlejnomu  fajlu,  mozhno vnov' i vnov' vyzyvat'
etu funkciyu, zagruzhaya vse novye i novye overlei. Esli pri vozvra-
te ustanovlen flag perenosa, to  byla oshibka i ee kod budet vozv-
rashchen v AX.  Kod raven 1, esli ukazan nevernyj nomer funkcii, 2 -
esli fajl ne najden, 5 - pri diskovyh  oshibkah i 8 - pri otsutst-
vii dostatochnoj pamyati.
   Posle  togo kak overlej zagruzhen v pamyat', k nemu mozhno  polu-
chit' dostup kak k  dalekoj  (far)  procedure.  V  segmente dannyh
dolzhen  byt' ustanovlen dvuhslovnyj ukazatel', opredelyayushchij  etot
vyzov.  Segmentnaya chast' ukazatelya prosto ravna tekushchemu kodovomu
segmentu.   Smeshchenie  overleya dolzhno byt'  vychisleno  nahozhdeniem
raznicy mezhdu segmentami koda i  overleya  i umnozheniem rezul'tata
na 16 (perevodya velichinu iz paragrafov v bajty).  V nizhepriveden-
nom primere dve  peremennye  OVERLAY_OFFSET  i  CODE_SEG pomeshcheny
odna za drugoj dlya pravil'noj ustanovki ukazatelya. Odnazhdy zagru-
zhennyj, overelej zatem  mozhem  vyzyvat'sya  instrukciej CALL DWORD
PTR OVERLAY_OFFSET.
   Overlej  mozhet  byt'  polnoj programmoj so  svoimi  segmentami
dannyh i steka, hotya kak  pravilo  ispol'zuetsya  stekovyj segment
vyzyvayushchej  programmy.  Pri vyzove overleya znachenie segmenta  ego
sobstvennogo segmenta dannyh dolzhno byt' pomeshcheno v DS.

;---zavershaem programmu fiktivnym segmentom (sm. [1.3.1]):
ZSEG         SEGMENT
ZSEG         ENDS

;---v segmente dannyh
OVERLAY_SEG    DW    ?
OVERLAY_OFFSET DW    ?             ;smeshchenie overleya
CODE_SEG       DW    ?             ;segment overleya - dolzhen
PATH           DB    'A:OVERLAY.EXE' ;sledovat' za smeshcheniem
0BLOCK         DD    0             ;4-bajtnyj blok parametrov

;---osvobozhdaem pamyat'
   MOV   CODE_SEG,CS     ;sozdaem kopiyu CS
   MOV   AX,ES           ;kopiruem znachenie segmenta PSP
   MOV   BX,ZSEG         ;adres segmenta konca programmy
   SUB   BX,AX           ;vychislyaem raznost'
   MOV   AH,4AH          ;nomer funkcii SETBLOCK
   INT   21H             ;osvobozhdaem pamyat'
   JC    SETBLK_ERR      ;flag perenosa govorit ob oshibke
;---otvodim pamyat' dlya overleya
   MOV   BX,100H         ;otvodim dlya overleya 1000H bajt
   MOV   AH,48H          ;funkciya otvedeniya pamyati
   INT   21H             ;teper' AX:0 ukazyvaet na blok
   JC    ALLOCATION_ERR  ;flag perenosa govorit ob oshibke
   MOV   OVERLAY_SEG,AX  ;zapasaem adres segmenta overleya
;---vychislenie smeshcheniya overleya v kodovom segmente
   MOV   AX,CODE_SEG     ;vychitaem znachenie segmenta overleya
   MOV   BX,OVERLAY_SEG  ;iz znacheniya segmenta koda
   SUB   BX,AX           ;BX soderzhit chislo paragrafov
   MOV   CL,4            ;sdvigaem eto chislo na 4 bita vlevo
   SHL   BX,CL           ;chtoby poluchit' velichinu v bajtah
   MOV   OVERLAY_OFFSET,BX  ;zapominaem smeshchenie


;---zagruzka pervogo overleya
   MOV   AX,SEG BLOCK    ;ES:BX ukazyvaet na blok parametrov
   MOV   ES,AX           ;
   MOV   BX,OFFSET BLOCK ;
   MOV   AX,OVERLAY_SEG  ;pomeshchaem adres segmenta overleya v
   MOV   [BX],AX         ;pervoe slovo bloka parametrov
   MOV   [BX]+2,AX       ;segment overleya - faktor privyazki
   LEA   DX,PATH         ;DS:DX ukazyvaet na put' k fajlu
   MOV   AH,48H          ;nomer funkcii EXEC
   MOV   AL,3            ;kod zagruzki overleya
   INT   21H             ;zagruzhaem overlej
   JC    LOAD_ERROR      ;flag perenosa govorit ob oshibke
;---teper' programma zanimaetsya svoimi delami
    .
    .
   CALL  DWORD PTR OVERLAY_OFFSET  ;vyzov overleya
    .     ;nuzhno ukazyvat' DWORD PTR, tak kak overlej -
    .     ;dalekaya procedura

;---posmotrite etu strukturu, kogda budete pisat' overlej
DSEG     SEGMENT     ;kak obychno, ustanavlivaem segment dannyh
            .        ;opuskaem stekovyj segment (ispol'zuetsya
            .        ;stek vyzyvayushchej programmy)
DSEG     ENDS

CSEG     SEGMENT     PARA PUBLIC 'CODE'
OVERLAY  PROC FAR      ;vsegda "dalekaya" procedura
         ASSUME CS:CSEG,DS:DSEG
         PUSH   DS     ;hranim DS vyzyvayushchej programmy
         MOV    AX,DSEG;ustanavlivaem DS overleya
         MOV    DS,AX
          .
          .
         POP    DS     ;vosstanavlivaem DS pri zavershenii
         RET
OVERLAY  ENDP
CSEG     ENDS
         END





   Programmisty  na  assemblere imeyut  vozmozhnost'  preobrazovat'
svoi programmy iz obychnogo  formata  EXE v format COM.  Fajly EXE
imeyut zagolovok, soderzhashchij informaciyu dlya privyazki; DOS privyazy-
vaet nekotorye adresa programmy pri  zagruzke.  S drugoj storony,
fajly  COM sushchestvuyut v takom vide, chto privyazka ne  trebuetsya  -
oni hranyatsya uzhe v tom  vide,  v  kotorom  zagruzhaemaya  programma
dolzhna byt' v pamyati mashiny. Po etoj prichine fajly EXE po men'shej
mere na 768 bajtov bol'she na  diske, chem ih COM ekvivalenty (hotya
pri zagruzke v pamyat' oni budut zanimat' odinakovoe mesto). Fajly
COM takzhe bystree zagruzhayutsya,  poskol'ku  ne trebuetsya privyazki.
Drugih preimushchestv u nih net, a nekotorye programmy slishkom slozh-
ny i slishkom veliki, chtoby ih mozhno bylo preobrazovat' v tip COM.
   Privyazka - eto process ustanovki adresov, svyazannyh s segment-
nym  registrom.   Naprimer, programma mozhet ukazyvat'  na  nachalo
oblasti dannyh sleduyushchim kodom:
   MOV   DX,OFFSET DATA_AREA
   MOV   AX,SEG DATA_AREA
   MOV   DS,AX
Smeshchenie v DX svyazano s  ustanovkoj  segmentnogo registra DS.  No
kakoe  znachenie dolzhen prinimat' sam DS? Programma trebuet  abso-
lyutnyj adres, no nomer  paragrafa,  v kotorom budet raspolagat'sya
DATA_AREA zavisit ot togo, v kakoe mesto v pamyati budet zagruzhena
programma - a eto  zavisit  ot  versii  MS  DOS, a takzhe ot togo,
kakie  rezidentnye  programmy budut nahodit'sya v mladshih  adresah
pamyati. Po etoj prichine vo vremya komponovki programmy mozhno tol'-
ko ustanovit' nekotorye segmentnye znacheniya cherez smeshcheniya  otno-
sitel'no nachala programmy.  Zatem, kogda DOS osushchestvlyaet privyaz-
ku, znachenie nachal'nogo adresa programmy  pribavlyaetsya k segment-
nym  znacheniyam, davaya absolyutnye adresa,  trebuemye v  segmentnom
registre. Na ris. 1-6 pokazan process privyazki.
   Fajly  COM  ne nuzhdayutsya v privyazke, poskol'ku oni hranyatsya  v
takom vide, chto ne nuzhdayutsya v fiksacii segmenta. Vse v programme
hranitsya otnositel'no nachala kodovogo segmenta, vklyuchaya vse  dan-
nye i stek. Po  etoj  prichine  vsya  programma  ne mozhet prevyshat'
65535  bajt  po dline, chto sootvetstvuet maksimal'nomu  smeshcheniyu,
kotoroe sushchestvuet  v  ispol'zuemoj  sheme  adresacii  (poskol'ku
verhnyaya chast' etogo bloka zanyata stekom, to real'noe prostranstvo
dostupnoe dlya koda i dannyh  nemnogo  men'she chem 65535 bajt, hotya
stekovyj  segment pri neobhodimosti mozhet byt' vynesen za granicu
64K bajtnogo bloka).  V fajlah COM vse segmentnye registry ukazy-
vayut na nachalo PSP; sravnite s fajlami EXE, gde DS i ES iniciali-
ziruyutsya  analogichnym  obrazom,  no  CS  ukazyvaet na pervyj bajt
sleduyushchij za PSP.
   Dlya  predstavleniya programmy v vide fajla COM trebuetsya soblyu-
denie sleduyushchih pravil:

   1.  Ne oformlyajte programmu v  vide  procedury.  Vmesto etogo,
pomestite v samoe nachalo metku, vrode START, i zavershite program-
mu operatorom END START.
   2. Pomestite v nachale programmy operator ORG 100H. |tot opera-
tor ukazyvaet nachalo koda (t.e.  ustanavlivaet schetchik  kommand).


Programmy COM  nachinayutsya  s  100H,  chto  yavlyaetsya pervym bajtom,
sleduyushchim  za PSP, poskol'ku CS ukazyvaet na nachalo PSP,  kotoroe
raspolozheno na 100H bajt nizhe. Dlya togo chtoby nachat' vypolnenie s
lyubogo drugogo mesta pomestite po adresu 100H instrukciyu JMP.
   3.   Operator  ASSUME dolzhen ustanavlivat' DS, ES i  SS  takim
obrazom, chtoby oni sovpadali so znacheniem  dlya kodovogo segmenta,
naprimer, ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG.
   4.  Dannye programmy mogut pomeshchat'sya v lyubom meste programmy,
do teh por, poka oni ne peremeshany s kodom.  Luchshe nachinat' prog-
rammy  s oblasti dannyh, poskol'ku makroassembler mozhet  vydavat'
soobshcheniya ob oshibkah pri pervom  prohode,  esli imeyutsya ssylki na
identifikator  dannyh, kotoryj eshche ne obnaruzhen.  Dlya perehoda  k
nachalu koda ispol'zujte v kachestve pervoj komandy programmy inst-
rukciyu JMP.
   5.   Nel'zya  ispol'zovat' fiksaciyu segmentov tipa  MOV  AX,SEG
NEW_DATA. Dostatochno ukazaniya odnogo smeshcheniya metki. V chastnosti,
nuzhno  opuskat' obychnyj kod, ispol'zuemyj v nachale programmy  dlya
ustanovki segmenta dannyh, MOV AX,DSEG / MOV DS,AX.
   6. Stekovyj segment  polnost'yu  opuskaetsya  v  nachal'nom kode.
Ukazatel' steka inicializiruetsya na vershinu adresnogo prostranst-
va 64K,  ispol'zuemogo  programmoj  (napominaem,  chto stek rastet
vniz v pamyati). V programmah COM on dolzhen byt' sdelan men'she chem
64K, SS i SP mogut byt' izmeneny. Imejte vvidu, chto pri komponov-
ke programmy komponovshchik vydast soobshchenie ob oshibke, ukazyvayushchee,
chto segment steka otsutstvuet. Ignorirujte ego.
   7. Zavershite programmu libo  instrukciej RET, libo preryvaniem
20H.   Preryvanie  20H - eto standartnaya funkciya  dlya  zaversheniya
programmy i vozvrata upravleniya  v  DOS. Dazhe kogda programma za-
vershaetsya  instrukciej RET, na samom dele ispol'zuetsya preryvanie
20H.  |to proishodit potomu, chto  vershina steka pervonachal'no so-
derzhit 0.  Pri vypolnenii zavershayushchej instrukcii programmy RET, 0
vytalkivaetsya iz  steka,  perenaznachaya  schetchik  komand na nachalo
PSP.  Nahodyashchayasya v etoj yachejke funkciya 20H, vypolnyaetsya kak sle-
duyushchaya instrukciya programmy,  vyzyvaya  peredachu upravleniya v DOS.
Vse eto oznachaet, chto Vam ne  nado  pri starte programmy pomeshchat'
na stek DS i 0 (PUSH DS / MOV AX,0 / PUSH AX), kak eto  trebuetsya
dlya EXE fajlov.

   Posle togo kak  programma  skonstruirovana  takim obrazom, as-
semblirujte i komponujte ee kak obychno.  Zatem preobrazujte ee  v
formu COM c pomoshch'yu utility EXE2BIN, imeyushchejsya v MS DOS. Esli imya
programmy, postroennoj komponovshchikom MYPROG.EXE, to prosto vvedi-
te komandu EXE2BIN MYPROG. V  rezul'tate  Vy poluchite programmnyj
fajl s imenem MYPROG.BIN.  Vse chto Vam ostanetsya posle etogo sde-
lat' - pereimenovat' etot  fajl  v  MYPROG.COM.   Vy mozhete takzhe
srazu ispol'zovat' komandu EXE2BIN MYPROG MYPROG.COM, dlya poluche-
niya fajla s rasshireniem COM.

   Nizkij uroven'.

   V dannom primere soderzhitsya polnaya korotkaya programma, kotoraya
po  ustanovke pereklyuchatelej opredelyaet kolichestvo nakopitelej  v
mashine i zatem  vyvodit  soobshchenie  na  ekran.  Ona mozhet sluzhit'
primerom  korotkoj  utility  togo sorta, dlya kotoryh  format  COM
idealen.


CSEG          SEGMENT
              ORG 100H
              ASSUME CS:CSEG, DS:CSEG, SS:CSEG
;---dannye
START:        JMP  SHORT BEGIN  ;perehod k kodu
MESSAGE1      DB   'The dip switches are set for $'
MESSAGE2      DB   'disk drive(s).$'
;---pechat' pervoj chasti soobshcheniya
BEGIN:        MOV  AH,9    ;funkciya 9 preryvaniya 21H - vyvod
              MOV  DX,OFFSET MESSAGE1  ;stroki
              INT  21H     ;vyvodim stroku
              PUSH AX      ;sohranyaem nomer funkcii na budushchee
;---poluchaem ustanovku pereklyuchatelej iz porta A mikroshemy 8255
              IN   AL,61H  ;poluchaem bajt iz porta B
              OR   AL,10000000B  ;ustanavlivaem bit 7
              OUT  61H,AL        ;zamenyaem bajt
              IN   AL,60H        ;poluchaem ustanovku pereklyuchat.
              AND  AL,11000000B  ;vydelyaem starshie 2 bita
              MOV  CL,6          ;podgotovka k sdvigu AL vpravo
              SHR  AL,CL         ;sdvigaem 2 bita v nachalo
              ADD  AL,49         ;dobavlyaem 1, chtoby schitat' s 1
                                 ;i 48 dlya perevoda v ASCII
              MOV  DL,AL         ;pomeshchaem rezul'tat v DL
              MOV  AL,61H        ;dolzhny vosstanovit' port B
              AND  AL,01111111B  ;sbrasyvaem bit 7
              OUT  61H,AL        ;vozvrashchaem bajt
;---pechat' chisla nakopitelej
              MOV  AH,2          ;funkciya 2 preryvaniya 21H
              INT  21H           ;pechataem chislo iz DL
;---pechat' vtoroj poloviny soobshcheniya
              POP  AX            ;berem nomer funkcii so steka
              MOV  DX,OFFSET MESSAGE2
              INT  21H           ;vyvodim stroku
              INT  20H           ;zavershenie programmy
CSEG          ENDS
              END START







   Vse  IBM PC ispol'zuyut mikroshemu tajmera 8253 (ili 8254)  dlya
soglasovaniya impul'sov ot mikroshemy sistemnyh chasov.  CHislo cik-
lov  sistemnyh chasov preobrazuetsya v odin  impul's, a  posledova-
tel'nost' etih impul'sov  podschityvaetsya dlya opredeleniya vremeni,
ili  oni  mogut byt' poslany na gromkogovoritel'  komp'yutera  dlya
generacii zvuka opredelennoj chastoty.   Mikroshema 8253 imeet tri
identichnyh nezavisimyh kanala, kazhdyj iz kotoryh mozhet programmi-
rovat'sya.
   Mikroshema 8253 rabotaet  nezavisimo  ot processora. Processor
programmiruet mikroshemu i zatem obrashchaetsya k drugim delam. Takim
obrazom 8253 dejstvuet kak chasy  real'nogo  vremeni - ona schitaet
svoi  impul'sy nezavisimo ot togo, chto  proishodit v  komp'yutere.
Odnako, maksimal'nyj  programmiruemyj interval sostavlyaet pribli-
zitel'no 1/12 sekundy.  Dlya podscheta intervalov vremeni v chasy  i
minuty nuzhny kakie-to drugie  sredstva.   Imenno  po etoj prichine
impul'sy  ot nulevogo kanala mikroshemy tajmera  nakaplivayutsya  v
peremennoj, nahodyashchejsya v oblasti dannyh BIOS. |tot process poka-
zan na ris.  2-1. |to nakoplenie obychno nazyvaetsya podschetom vre-
meni sutok.  18.2 raza  v  sekundu  vyhod kanala 0 obrabatyvaetsya
apparatnym  preryvaniem (preryvaniem tajmera), kotoroe  nenadolgo
ostanavlivaet  processor  i  uvelichivaet  schetchik  vremeni sutok.
CHislo  0  sootvetstvuet  polnochi 12:00; kogda  schetchik  dostigaet
znacheniya ekvivalentnogo 24 chasam, on sbrasyvaetsya na nol'. Drugoe
vremya  v  techenie sutok legko  opredelyaetsya  deleniem  pokazatelya
schetchika na 18.2 dlya kazhdoj  sekundy.   Schetchik vremeni sutok is-
pol'zuetsya v bol'shinstve operacij, svyazannyh so vremenem.





   Kazhdyj  iz treh kanalov mikroshemy tajmera 8253 (8254 dlya  AT)
sostoit iz treh registrov. Dostup k kazhdoj gruppe iz treh regist-
rov  osushchestvlyaetsya cherez odin port; nomera portov ot 40H do  42H
sootvetstvuyut kanalam 0 -  2.  Port  svyazan  s 8-bitnym registrom
vvoda/vyvoda, kotoryj posylaet i prinimaet dannye dlya etogo kana-
la.  Kogda kanal  zaprogrammirovan, to cherez etot port posylaetsya
dvuhbajtnoe znachenie, mladshij bajt snachala.  |to chislo peredaetsya
v 16-bitnyj registr zadvizhki (latch register), kotoryj hranit eto
chislo i iz kotorogo kopiya pomeshchaetsya v 16-bitnyj registr  schetchi-
ka. V registre schetchika chislo  umen'shaetsya na edinicu kazhdyj raz,
kogda impul's ot sistemnyh chasov propuskaetsya cherez kanal.  Kogda
znachenie etogo chisla  dostigaet  nulya,  to  kanal vydaet vyhodnoj
signal i zatem novaya kopiya soderzhimogo registra zadvizhki peredvi-
gaetsya v registr schetchika,  posle  chego process povtoryaetsya.  CHem
men'she chislo v registre schetchika, tem bystree ritm. Vse tri kana-
la vsegda aktivny: processor ne vklyuchaet i ne vyklyuchaet ih. Teku-
shchee  znachenie lyubogo iz registrov schetchika mozhet byt' prochitano v
lyuboj moment vremeni, ne vliyaya na schet.
   Kazhdyj kanal imeet dve vhodnye i odnu vyhodnuyu linii. Vyhodnaya
liniya vyvodit impul'sy, voznikayushchie v rezul'tate podscheta. Nazna-
chenie etih signalov var'iruetsya v zavisimosti ot tipa IBM PC:

   Kanal 0 ispol'zuetsya sistemnymi chasami vremeni sutok. On usta-
navlivaetsya BIOS pri  starte  takim  obrazom, chto vydaet impul'sy
priblizitel'no  18.2 raza v sekundu.  4-bajtnyj schetchik etih  im-
pul'sov hranitsya v pamyati po adresu  0040:006C (mladshij bajt hra-
nitsya pervym).  Kazhdyj impul's iniciiruet preryvanie tajmera (no-
mer 8) i imenno eto  preryvanie  uvelichivaet  pokazanie schetchika.
|to  apparatnoe  preryvanie, poetomu ono  obrabatyvaetsya  vsegda,
nezavisimo ot togo, chem  zanyat  processor,  esli tol'ko razresheny
apparatnye preryvaniya (sm. obsuzhdenie v [1.2.2]).  Vyhodnaya liniya
ispol'zuetsya takzhe dlya sinhronizacii nekotoryh diskovyh operacij,
poetomu esli Vy izmenili ee znachenie, to Vam neobhodimo vosstano-
vit' pervonachal'noe znachenie pered obrashcheniem k disku.

   Kanal  1  upravlyaet obnovleniem pamyati na vseh  mashinah  krome
PCjr, poetomu ego luchshe ne  trogat'.  Vyhodnaya liniya etogo kanala
svyazana  s mikroshemoj pryamogo dostupa k pamyati [5.4.2] i ee  im-
pul's zastavlyaet  mikroshemu  DMA  obnovit'  vsyu pamyat'.  Na PCjr
kanal  1 sluzhit dlya preobrazovaniya vhodnyh dannyh s klaviatury iz
posledovatel'noj v parallel'nuyu formu. PCjr ne ispol'zuet mikros-
hemu  pryamogo  dostupa k pamyati, poetomu kogda  on  vmesto  etogo
progonyaet dannye cherez processor, to preryvanie ot tajmera zablo-
kirovano.  Kanal 1 ispol'zuetsya dlya podscheta zablokirovannyh  im-
pul'sov chasov vremeni  sutok,  s  tem  chtoby  mozhno bylo obnovit'
znachenie schetchika posle zaversheniya diskovyh operacij.

   Kanal  2 svyazan s gromkogovoritelem komp'yutera i on proizvodit
prostye pryamougol'nye impul'sy dlya  generacii zvuka. Programmisty
imeyut  bol'shij kontrol' nad vtorym kanalom, chem  nad  ostal'nymi.
Prostye zvuki mogut  generirovat'sya  odnovremenno s drugimi prog-
rammnymi operaciyami, a bolee slozhnye zvukovye effekty mogut  byt'


dostignuty za schet ispol'zovaniya  processora.  Kanal 2 mozhet byt'
otsoedinen  ot gromkogovoritelya i ispol'zovat'sya dlya  sinhroniza-
cii. Nakonec, vyhodnaya liniya kanala 2 svyazana s dinamikom komp'yu-
tera.   Odnako dinamik ne budet generirovat' zvuk do teh por poka
ne sdelany opredelennye ustanovki mikroshemy interfejsa s perife-
riej 8255.
   Dve  vhodnye linii dlya kazhdogo kanala sostoyat iz linii  chasov,
kotoraya peredaet signal ot  mikroshemy  sistemnyh  chasov i linii,
nazyvaemoj  vorotami (gate), kotoraya vklyuchaet i vyklyuchaet  signal
ot chasov. Vorota vsegda otkryty dlya signalov chasov po kanalam 0 i
1.  No oni mogut byt' zakrytymi dlya kanala 2, chto pozvolyaet neko-
torye special'nye manipulyacii so zvukom. Vorota zakryvayutsya usta-
novkoj  mladshego  bita porta s adresom 61H, kotoryj yavlyaetsya  re-
gistrom mikroshemy 8255; sbros etogo bita snova otkryvaet vorota.
|ta mikroshema obsuzhdaetsya v  [1.1.1].  Otmetim chto - kak i vyhod
kanala  2 - bit 1 porta 61H svyazan s dinamikom i takzhe mozhet  is-
po'zovat'sya dlya generacii zvuka. Na ris.  2-2 privedena diagramma
mikroshemy tajmera 8253.
   Mikroshema  tajmera mozhet ispol'zovat'sya  neposredstvenno  dlya
vremennyh operacij, no eto  redko  byvaet  udobnym.  Vvod s chasov
proizvoditsya  1.19318  millionov raz v sekundu (dazhe na  AT,  gde
sistemnye chasy idut bystree, mikroshema tajmera poluchaet signal s
chastotoj  1.19 Mgc).  Poskol'ku maksimal'noe chislo, kotoroe mozhet
hranit'sya v 16 bitah, ravno  65535  i poskol'ku eto chislo delitsya
na  chastotu impul'sov ot chasov, ravnuyu 18.2, to maksimal'nyj voz-
mozhnyj interval mezhdu impul'sami raven priblizitel'no 1/12 sekun-
dy.   Poetomu  bol'shinstvo vremennyh operacij ispol'zuyut  schetchik
vremeni sutok BIOS. Dlya podscheta vremeni chitaetsya znachenie vreme-
ni  sutok i sravnivaetsya s nekotorym ranee zapomnennym  znacheniem
dlya opredeleniya chisla  impul'sov,  proshedshih s togo momenta. Spe-
cial'nyj sposob, opisannyj v [2.1.7], pozvolyaet ispo'zovat' schet-
chik vremeni sutok dlya operacij v real'nom vremeni.
   8253 predostavlyaet razrabotchikam oborudovaniya 6 rezhimov raboty
dlya  kazhdogo kanala.  Programmisty obychno ogranichivayutsya  tret'im
rezhimom, kak dlya kanala 0 pri  sinhronizacii,  tak i dlya kanala 2
dlya sinhronizacii ili generacii zvuka.  V etom rezhime, kak tol'ko
registr zadvizhki poluchaet chislo, on  nemedlenno zagruzhaet kopiyu v
registr  schetchika.  Kogda znachenie v schetchike dostigaet nulya  re-
gistr zadvizhki mgnovenno perezagruzhaet  schetchik i t.d.  V techenie
poloviny otscheta vyhodnaya liniya vklyuchena, a v techenie poloviny  -
vyklyuchena. V rezul'tate  poluchayutsya  pryamougol'nye volny, kotorye
odinakovo prigodny kak dlya generacii zvuka, tak i dlya podscheta.
   8-bitnyj komandnyj registr upravlyaet sposobom zagruzki chisel v
kanal.  Adres porta dlya etogo registra raven 43H.  Komandnomu re-
gistru peredaetsya bajt, kotoryj govorit kakoj kanal  programmiro-
vat', v kakom rezhime, a takzhe odin ili oba bajta registra zadvizh-
ki  dolzhny byt' peredany.  On pokazyvaet takzhe budet li  chislo  v
dvoichnoj ili BCD (dvoichnokodirovannoj desyatichnoj) forme. Znachenie
bitov etogo registra takovo:


   bit   0    esli 0, dvoichnye dannye, inache BCD
       3-1    nomer rezhima, 1 - 5 (000 - 101)
       5-4    tip operacii:
                00 = peredat' znachenie schetchika v zadvizhku
                01 = chitat'/pisat' tol'ko starshij bajt
                10 = chitat'/pisat' tol'ko mladshij bajt
                11 = chitat'/pisat' starshij bajt, potom mladshij
       7-6    nomer programmiruemogo kanala, 0 - 2 (00 -10)

   Koroche  govorya, dlya programmirovaniya mikroshemy 8253 nado  vy-
polnit' tri osnovnyh  shaga.  Posle  togo kak tretij shag zavershen,
zaprogrammirovannyj  kanal nemedlenno nachinaet funkcionirovat' po
novoj programme.

   1.  Poslat' v  komandnyj  registr  (43H)  bajt, predstavlyayushchij
cepochku  bitov,  kotorye  vybirayut kanal,  status  chteniya/zapisi,
rezhim operacii i formu predstavleniya chisel.
   2.  Dlya kanala 2 nado razreshit' signal ot chasov, ustanoviv v 1
bit 0 porta s adresom 61H. (Kogda bit 1 etogo registra ustanovlen
v 1, to kanal 2 upravlyaet dinamikom.  Sbros'te ego v 0 dlya opera-
cij sinhronizacii.)
   3. Vychislite znachenie schetchika  ot 0 do 65535, pomestite ego v
AX,  i  poshlite snachala mladshij, a zatem starshij  bajt v  registr
vvoda/vyvoda kanala (40H - 42H).

   Kanaly mikroshemy 8253 rabotayut vsegda.  Po etoj prichine prog-
rammy vsegda dolzhny vosstanavlivat' nachal'nye ustanovki registrov
8253 pered zaversheniem. V chastnosti, esli pri zavershenii program-
my  generiruetsya zvuk, to on budet prodolzhat'sya dazhe posle  togo,
kak MS DOS poluchit upravlenie i zagruzit druguyu programmu. Imejte
eto vvidu pri napisanii procedury vyhoda po Ctrl-Break [3.2.8].

   Nizkij uroven'.

   V  dannom primere kanal 0 programmiruetsya na drugoe  znachenie,
chem ustanovleno BIOS  pri  starte.  Prichina  izmeneniya  ustanovki
sostoit v tom, chtoby izmenit' interval izmeneniya schetchika vremeni
sutok na bol'shuyu velichinu, chem  18.2  raza v sekundu. CHastota ob-
novleniya  schetchika  izmenyaetsya, skazhem, na 1000 raz v sekundu,  s
cel'yu provedeniya tochnyh laboratornyh izmerenij. Znachenie zadvizhki
dolzhno  byt' 1193 (1193180 taktov v sekundu / 10000).  Kak chitat'
tekushchee znachenie registra  schetchika  sm. v primere [2.1.8]. Pered
diskovymi  operaciyami original'noe znachenie zadvizhki dolzhno  byt'
vosstanovleno, poskol'ku kanal  0  ispol'zuetsya dlya sinhronizacii
diskovyh operacij.  Maksimal'no vozmozhnoe znachenie - 65535 taktov
chasov mezhdu impul'sami ot kanala - mozhet byt' dostignuto zasylkoj
0 v registr  zadvizhki  (0  nemedlenno  prevrashchaetsya  v  65535 pri
umen'shenii na edinicu.


;---ustanovka registrov vvoda/vyvoda
COMMAND_REG  EQU   43H         ;adres komandnogo registra
CHANNEL_0    EQU   40H         ;adres kanala 0
             MOV   AL,00110110B   ;ustanovka bitov dlya kanala 2
             OUT   COMMAND_REG,AL ;zasylka v komandnyj registr
;---posylka schetchika v zadvizhku
             MOV   AX,1193     ;schetchik dlya 100 impul'sov/sek.
             OUT   CHANNEL_2,AL   ;posylka mladshego bajta
             MOV   AL,AH       ;gotovim dlya posylki starshij bajt
             OUT   CHANNEL_2,AL   ;posylka starshego bajta





   Pri  starte MS DOS zaprashivaet u pol'zovatelya  tekushchee  vremya.
Vvedennoe znachenie pomeshchaetsya v 4 bajta, hranyashchie schetchik vremeni
sutok  (nachinaya s 0040:006C, mladshij bajt hranitsya  pervym).   No
snachala ono preobrazuetsya v formu, v kotoroj podschityvaetsya vremya
sutok, t.e.  vremya preobrazuetsya v  chislo vosemnadcatyh dolej se-
kundy, proshedshih s polnochi.  |to chislo postoyanno obnovlyaetsya 18.2
raz v sekundu preryvaniem  tajmera.   Kogda  poyavlyaetsya ocherednoj
zapros  na  vremya,  to tekushchee znachenie  schetchika  vremeni  sutok
preobrazuetsya obratno  v  privychnyj  format  chasy-minuty-sekundy.
Esli  pri starte ne bylo vvedeno znacheniya, to schetchik  ustanavli-
vaetsya v nol', kak budto sejchas  polnoch'.   Komp'yutery snabzhennye
mikroshemoj  kalendarya-chasov  mogut  avtomaticheski  ustanavlivat'
schetchik vremeni sutok.

   Vysokij uroven'.

   TIME$ ustanavlivaet ili poluchaet vremya v vide stroki chch:mm:ss,
gde chasy menyayutsya ot 0 do 23, nachinaya s polunochi. Dlya 5:10 dnya:

   100 TIME$ = "17:10:00"  'ustanovka vremeni
   110 PRINT TIME$         'vyvod vremeni

   Poskol'ku TIME$ vozvrashchaet stroku, to dlya vydeleniya  otdel'nyh
chastej pokazaniya chasov mozhno ispol'zovat' strokovye funkcii MID$,
LEFT$  i RIGHT$.  Naprimer, chtoby preobrazovat' vremya 17:10:00  v
5:10 Vy dolzhny vyrezat' stroku  simvolov,  sootvetstvuyushchuyu chasam,
preobrazovat'  ee v chislovoj vid (ispol'zuya funkciyu VAL), vychest'
12, a zatem predstavit' rezul'tat opyat' v vide stroki:

100 T$ = TIME$                'poluchaem stroku vremeni
110 HOUR$ = LEFT$(T$,2)       'vydelyaem znachenie chasov
120 MINUTES$ = MID$(T$,4,2)   'vydelyaem znachenie minut
130 NEWHOUR = VAL(HOUR$)      'preobrazuem chasy v chislo
140 IF NEWHOUR > 12 THEN NEWHOUR = NEWHOUR - 12
150 NEWHOUR$ = STR$(NEWHOUR)  'novoe znachenie v stroku
160 NEWTIME$ = NEWHOUR$ + ":" + MINUTES$  'delaem novuyu stroku

   Srednij uroven'.

   MS DOS predostavlyaet preryvaniya  dlya chteniya i ustanovki vreme-
ni, proizvodya neobhodimye preobrazovaniya mezhdu znacheniem schetchika
vremeni sutok i chasami-minutami-sekundami.  Vremya vydaetsya s toch-
nost'yu  do 1/100 sekundy, no poskol'ku schetchik vremeni sutok  ob-
novlyaetsya s chastotoj v pyat' raz  men'shej,  to pokazaniya sotyh se-
kund ochen' priblizhennye. Funkciya 2CH preryvaniya 21H vydaet vremya,
a  funkciya 2DH - ustanavlivaet ego.  V oboih sluchayah CH  soderzhit
chasy (ot 0 do 23, gde 0 sootvetstvuet polnochi), CL - minuty (ot 0
do  59), DH - sekundy (ot 0 do 59) i DL - sotye doli sekund (ot 0
do 99).


   Krome togo pri  poluchenii  vremeni  funkciej  2CH, AL soderzhit
nomer  dnya nedeli (0 = voskresen'e).  Znachenie dnya  budet  vernym
tol'ko esli byla ustanovlena data. DOS vychislyaet nomer dnya nedeli
po date.  Otmetim takzhe, chto pri ustanovke vremeni funkciej  2DH,
AL otmechaet  pravil'nost'  vvedennogo  znacheniya vremeni (0 = pra-
vil'no, FF = nepravil'no).

;---ustanovka vremeni
   MOV   CH,HOURS       ;vvodim znacheniya vremeni
   MOV   CL,MINUTES     ;
   MOV   DH,SECONDS     ;
   MOV   DL,HUNDREDTHS  ;
   MOV   AH,2DH         ;nomer funkcii ustanovki vremeni
   INT   21H            ;ustanavlivaem vremya
   CMP   AH,0FFH        ;proveryaem pravil'nost' znacheniya
   JE    ERROR          ;perehod na obrabotku oshibki

;---poluchenie vremeni
   MOV   AH,2CH         ;nomer funkcii polucheniya vremeni
   INT   21H            ;poluchaem vremya
   MOV   DAY_OF_WEEK,AH ;poluchaem den' nedeli iz AH

   Nizkij uroven'.

   Esli  Vy izmenili skorost' impul'sov kanala 1 mikroshemy  8253
dlya special'nyh prilozhenij, to  Vam neobhodimo napisat' svoyu pro-
ceduru dekodirovaniya pokazanij schetchika vremeni sutok.  BIOS poz-
volyaet diapazon znachenij  schetchika  ot  0 do 1.573 milliona i eto
mozhet  byt' izmeneno tol'ko putem izmeneniya  preryvaniya  tajmera.
Poetomu chasy, real'no  pokazyvayushchie  sotye doli sekundy, ne mogut
rabotat'  24  chasa bez special'no napisannoj programmy.   Otmetim
takzhe, chto bajt 0040:0070  ustanavlivaetsya  v  nol' pri starte, a
zatem uvelichivaetsya na 1 (ne bol'she) po hodu chasov.





   Pri  vklyuchenii  komp'yutera MS DOS  zaprashivaet u  pol'zovatelya
tekushchie  datu i vremya.  Vremya zapisyvaetsya v oblasti dannyh BIOS.
Data zhe soderzhitsya  v  peremennoj  v  COMMAND.COM. Ona hranitsya v
formate treh posledovatel'nyh bajtov, kotorye soderzhat sootvetst-
venno den' mesyaca, nomer mesyaca  i nomer goda, nachinaya s 0, gde 0
sootvetstvuet  1980 godu.  V otlichii ot schetchika  vremeni  sutok,
adres daty v pamyati menyaetsya s izmeneniem versii DOS i polozheniem
v pamyati COMMAND.COM.  Po etoj prichine dlya polucheniya daty  vsegda
nado ispol'zovat' gotovye  utility Bejsika ili MS DOS, a ne obra-
shchat'sya k etoj peremennoj napryamuyu.
   Mashiny,  oborudovannye mikroshemoj kalendarya-chasov,  avtomati-
cheski ustanavlivayut vremya i datu  s pomoshch'yu special'noj programmy
(obychno  zapuskaemoj  pri starte cherez fajl  AUTOEXEC.BAT).   Kak
poluchit' dostup k mikrosheme kalendarya-chasov,  sm. [2.1.4]. Otme-
tim  takzhe, chto kogda schetchik vremeni sutok BIOS perehodit  cherez
otmetku 24 chasov, MS DOS menyaet datu.

   Vysokij uroven'.

   Operator Bejsika DATE$ ustanavlivaet  ili poluchaet datu v vide
stroki  formata  MM-DD-GGGG.  Mozhno ispol'zovat' kosuyu chertu  (/)
vmesto defisa (-).  Pervye dve cifry goda mogut byt' opushcheny. Dlya
31-go oktyabrya 1984 g.:

   100 DATE$ = "10/31/84"     'ustanovka daty
   110 PRINT DATE$            'vyvod daty

   ... i na displee budet vyvedeno: 10-31-1984.

   Srednij uroven'.

   Funkcii  2AH  i  2BH preryvaniya 21H  poluchayut i  ustanavlivayut
datu.  Dlya polucheniya daty pomestite v AH 2AH i vypolnite preryva-
nie.   Pri vozvrate CX budet soderzhat' god v vide chisla  ot 0  do
119, chto sootvetstvuet  diapazonu  let 1980 - 2099 (mozhno skazat'
chto  vydaetsya smeshchenie otnositel'no 1980 g.).  DH soderzhit  nomer
mesyaca, a DL - den'.

   MOV   AH,2AH       ;nomer funkcii polucheniya daty
   INT   21H          ;poluchenie daty
   MOV   DAY,DL       ;den' iz DL
   MOV   MONTH,DH     ;mesyac iz DH
   ADD   CX,1980      ;dobavlyaem bazu k godu
   MOV   YEAR,CX      ;poluchaem nomer goda

   Dlya ustanovki daty pomestite den', mesyac i god v te zhe regist-
ry  i vypolnite funkciyu 2BH.  Esli znacheniya, ukazannye  dlya  daty
neverny, to v AL budet vozvrashcheno FF, v protivnom sluchae - 0.


   MOV   DL,DAY       ;pomeshchaem den' v DL
   MOV   DH,MONTH     ;pomeshchaem mesyac v DH
   MOV   CX,YEAR      ;pomeshchaem god v CX
   SUB   CX,1980      ;berem smeshchenie otnositel'no 1980
   MOV   AH,2BH       ;nomer funkcii ustanovki daty
   INT   21H          ;ustanovka daty
   CMP   AH,0FFH      ;proveryaem uspeshnost' operacii
   JE    ERROR        ;nevernaya data, idem na obrabotku oshibki





   CHasy real'nogo vremeni imeyut svoj sobstvennyj processor, koto-
ryj mozhet podschityvat' vremya ne vliyaya na drugie komp'yuternye ope-
racii. Oni imeyut takzhe nezavisimyj istochnik pitaniya, ispol'zuemyj
kogda komp'yuter  vyklyuchen.   Programmno  mozhno  kak chitat', tak i
ustanavlivat' chasy rel'nogo vremeni.  Obychno imeetsya dopolnitel'-
noe programmnoe obespechenie, kotoroe ustanavlivaet schetchik vreme-
ni  sutok  BIOS i peremennuyu daty DOS takim  obrazom,  chtoby  oni
sootvetstvovali tekushchim  pokazaniyam  chasov real'nogo vremeni.  No
mozhno  programmno proverit' sootvetstvie mezhdu nimi i pri obnaru-
zhenii raznoglasij prinyat' neobhodimye mery.
   Razlichnye ustanovki vremeni i daty  osushchestvlyayutsya cherez nabor
adresov  portov.  Mnogie mnogofunkcional'nye platy rasshireniya dlya
IBM PC imeyut chasy real'nogo  vremeni,  no, k sozhaleniyu, net stan-
dartnoj  mikroshemy i diapazona adresov portov.   AT  oboruduetsya
chasami  real'nogo  vremeni,  osnovannymi  na  mikrosheme MC146818
firmy  Motorola, kotorye ispol'zuyut te zhe registry, chto i mikros-
hema, soderzhashchaya dannye  o  konfiguracii  sistemy.  Dostup k etim
registram mozhno poluchit', poslav snachala nomer trebuemogo regist-
ra v port 70H, a zatem prochitav znachenie registra cherez port 71H.
Registry, svyazannye s chasami, sleduyushchie:

           Nomer registra              Funkciya

                00H                  Sekundy
                01H                  Sekundnaya trevoga
                02H                  Minuty
                03H                  Minutnaya trevoga
                04H                  CHasy
                05H                  CHasovaya trevoga
                06H                  Den' nedeli
                07H                  Den' mesyaca
                08H                  Mesyac
                09H                  God
                0AH                  registr statusa A
                0BH                  registr statusa B
                0CH                  registr statusa C
                0DH                  registr statusa D

   Bity  chetyreh statusnyh registrov vypolnyayut razlichnye funkcii,
iz kotoryh interes dlya  programmistov  mogut predstavlyat' sleduyu-
shchie:
   Registr A: bit 7   1 = idet modifikaciya vremeni (nado zhdat'
                          znacheniya 0, chtoby chitat')
   Registr B: bit 6   1 = razresheno periodicheskoe preryvanie
              bit 5   1 = razresheno preryvanie trevogi
              bit 4   1 = razresheno preryvanie konca modifikacii
              bit 1   1 = chasy schitayutsya do 24, 0 = do 12
              bit 0   1 = razresheno zapominanie vremeni sutok


   CHasy  real'nogo vremeni na AT mogut vyzyvat' apparatnoe prery-
vanie IRQ8. Programma mozhet ustanovit' vektor etogo preryvaniya na
lyubuyu proceduru, kotoruyu trebuetsya vypolnit' v opredelennoe vremya
[1.2.3].  Ispol'zujte vektor  4AH.   Operacii v real'nom vremeni,
proizvodimye  takim  obrazom, menee hlopotny, chem  obsuzhdaemye  v
[2.1.7] (hotya i cenoj  kompaktnosti  programm).  Preryvanie mozhet
vyzyvat'sya odnim iz treh sposobov, kazhdyj iz kotoryh zapreshchen pri
starte.   Periodicheskoe preryvanie proishodit cherez  opredelennye
intervaly vremeni.   Periodichnost' priblizhenno ravna odnoj milli-
sekunde.   Preryvanie trevogi proishodit kogda znachenie treh  re-
gistrov trevogi sovpadaet so znacheniyami sootvetstvuyushchih vremennyh
registrov.  Preryvanie konca modifikacii proishodit posle kazhdogo
obnovleniya znachenij registrov mikroshemy.
   Preryvanie 1AH rasshireno v BIOS AT, chtoby ono pozvolyalo chitat'
i ustanavlivat' chasy real'nogo vremeni.  Poskol'ku pokazaniya  ni-
kogda ne sostoyat bolee chem ih  dvuh  desyatichnyh cifr, to znacheniya
vremeni  vydayutsya v dvoichno-kodirovannoj desyatichnoj forme  (BCD),
kogda bajt delitsya na  dve  poloviny  i  kazhdaya  desyatichnaya cifra
predstavlyaetsya  chetyr'mya  bitami.  Takoj format  pozvolyaet  legko
perevodit' chisla v formu ASCII.  Programme  nuzhno tol'ko sdvinut'
polovinu bajta v mladshij konec registra i dobavit' 48 dlya poluche-
niya koda ASCII,  sootvetstvuyushchego  dannomu chislu. Dlya vseh IBM PC
funkcii  0 i 1 preryvaniya 1AH chitayut i ustanavlivayut schetchik vre-
meni sutok BIOS.  Dlya  chasov  real'nogo  vremeni AT imeetsya shest'
novyh funkcij:

   Funkciya 2:  CHtenie vremeni iz chasov real'nogo vremeni
               Pri vozvrate: CH = chasy v BCD
                             CL = minuty v BCD
                             DH = sekundy v BCD
   Funkciya 3:  Ustanovka vremeni chasov real'nogo vremeni
               Pri vhode: CH = chasy v BCD
                          CL = minuty v BCD
                          DH = sekundy v BCD
                          DL = if daylight savings, else 1
   Funkciya 4:  CHtenie daty iz chasov real'nogo vremeni
               Pri vozvrate: CH = vek v BCD (19 ili 20)
                             CL = god v BCD (s 1980)
                             DH = mesyac v BCD
                             DL = den' mesyaca v BCD
   Funkciya 5:  Ustanovka daty chasov real'nogo vremeni
               Pri vhode:    CH = vek v BCD (19 ili 20)
                             CL = god v BCD (s 1980)
                             DH = mesyac v BCD
                             DL = den' mesyaca v BCD
   Funkciya 6:  Ustanovka trevogi dlya chasov real'nogo vremeni
               Pri vhode: CH = chasy v BCD
                          CL = minuty v BCD
                          DH = sekundy v BCD
   Funkciya 7:  Sbros trevogi (net vhodnyh registrov)

Trevoga ustanavlivaetsya kak  smeshchenie,  otnositel'no tekushchego mo-
menta vremeni. Maksimal'nyj period raven 23:59:59.  Kak uzhe govo-
rilos' vyshe, vektor preryvaniya  4AH dolzhen ukazyvat' na proceduru
obrabotki trevogi.  Otmetim, chto esli chasy ne rabotayut  (naibolee
veroyatno, iz-za otsutstviya pitaniya), to vypolnenie funkcij 2, 4 i
6 ustanavlivaet flag perenosa.





   Esli Vy osushchestvlyaete zaderzhku v programme posredstvom pustogo
cikla, to Vam mozhet  potrebovat'sya  mnogo vremeni dlya togo, chtoby
dobit'sya  nuzhnogo vremeni zaderzhki.  Dazhe esli Vy opredelite tre-
buemuyu dlitel'nost', to nel'zya byt' uverennym, chto Vasha programma
budet  davat' nuzhnoe vremya zaderzhki pri vseh usloviyah.   Dlitel'-
nost' cikla mozhet menyat'sya v  zavisimosti ot ispol'zuemogo kompi-
lyatora  (ili,  dlya Bejsika, ot togo, kompiliruetsya programma  ili
net). A v nashe vremya, kogda imeetsya bol'shoj nabor mashin sovmesti-
myh  s  IBM PC - imeyushchih shirokij diapazon skorosti  processora  -
dazhe cikl na yazyke assemblera mozhet  privodit' k razlichnym vreme-
nam  zaderzhki.  Poetomu razumno opredelyat' vremya programmnoj  za-
derzhki neposredstvenno  po  chasam.   CHastota  otscheta 18.2 raza v
sekundu,  ispol'zuemaya  dlya modifikacii schetchika  vremeni  sutok,
dolzhna vpolne udovletvoryat'  bol'shinstvo potrebnostej (kak uveli-
chit' chastotu otschetov sm. [2.1.1]).
   CHtoby  obespechit' zaderzhku dannoj prodolzhitel'nosti, programma
dolzhna podschitat'  trebuemoe  chislo  impul'sov  schetchika  vremeni
sutok.   |to znachenie dobavlyaetsya k schitannomu tekushchemu  znacheniyu
schetchika. Zatem programma postoyanno schityvaet znachenie schetchika i
sravnivaet  ego  s zapomnennym.  Kogda dostigaetsya ravenstvo,  to
trebuemaya zaderzhka proshla i mozhno  prodolzhat' vypolnenie program-
my.   CHetyre bajta, v kotoryh hranitsya znachenie schetchika  vremeni
sutok hranyatsya, nachinaya s adresa 0040:006C (kak obychno, nachinaya s
mladshego bajta). Dlya zaderzhek men'shih 14 sekund mozhno pol'zovat'-
sya tol'ko mladshim bajtom. Dva mladshih bajta pozvolyayut zaderzhki do
odnogo chasa (tochnee, na pol-sekundy men'she, chem chas).

   Vysokij uroven'.

   V  Bejsike mozhno ispol'zovat' operator SOUND [2.2.2] so znache-
niem chastoty, ravnym 32767. V etom sluchae zvuk ne budet generiro-
vat'sya voobshche.  |to otsutstvie zvuka budet dlit'sya stol'ko otsche-
tov vremeni sutok, skol'ko Vy ukazhete.   Dlya 5-sekundnoj zaderzhki
nuzhen 91 otschet (5 * 18.2). Poetomu

100 SOUND 32767,91  'ostanavlivaet programmu na 5 sekund

Dlya pryamogo chteniya schetchika vremeni sutok nuzhno:

100 DEF SEG = 0            'ustanovka segmenta na nachalo pamyati
110 LOWBYTE = PEEK(&H46C)  'poluchenie mladshego bajta
120 NEXTBYTE = PEEK(&H46D) 'poluchenie sleduyushchego bajta
130 LOWCOUNT = NEXTBYTE*256 + LOWBYTE  'znachenie dvuh bajtov

   Srednij uroven'.

   Prochitajte  znachenie  schetchika vremeni sutok  BIOS,  ispol'zuya
funkciyu 0 preryvaniya 1AH  i  dobav'te  k  nemu  neobhodimoe chislo
impul'sov po 1/18 sekundy.  Posle etogo schityvajte tekushchie znache-
niya schetchika vremeni sutok, postoyanno sravnivaya s trebuemoj veli-
chinoj. Pri dostizhenii ravenstva nado konchat' zaderzhku. Preryvanie
1AH vozvrashchaet dva mladshih bajta v DX (bol'shinstvo zaderzhek ukla-


dyvayutsya  v etih predelah), poetomu dva starshih bajta, vozvrashchae-
mye  v  CX,  mogut  ignorirovat'sya,  chto  pozvolit  Vam  izbezhat'
32-bajtnyh operacij.  V dannom primere ustanovlena zaderzhka na  5
sekund, chto sootvetstvuet 91 otschetu.

;---poluchenie znacheniya schetchika i ustanovka zaderzhki
            MOV   AH,0   ;nomer funkcii dlya "chteniya"
            INT   1AH    ;poluchaem znachenie schetchika
            ADD   DX,91  ;dobavlyaem 5 sek. k mladshemu slovu
            MOV   BX,DX  ;zapominaem trebuemoe znachenie v BX
;---postoyannaya proverka znacheniya schetchika vremeni sutok BIOS
REPEAT:     INT   1AH    ;poluchaem znachenie schetchika
            CMP   DX,BX  ;sravnivaem s iskomym
            JNE   REPEAT ;esli neraven, to povtoryaem snova
                         ;inache, zaderzhka okonchena

AT imeet dobavochnuyu  funkciyu  preryvaniya  15H,  kotoraya pozvolyaet
osushchestvit'  zaderzhku na ukazannoe vremya.  Pomestite 86H v AH,  a
chislo mikrosekund zaderzhki v CX:DX.  Posle etogo vypolnite prery-
vanie.





   Programma opredelyaet vremya dlya vypolneniya opredelennoj  opera-
cii v tochnosti tak zhe, kak i chelovek: beretsya nachal'noe pokazanie
schetchika  vremeni sutok i zatem sravnivaetsya s posleduyushchimi poka-
zaniyami.  Mozhno poluchat'  znacheniya v formate chasy-minuty-sekundy,
no  slishkom hlopotno vychislyat' raznicu mezhdu takimi  pokazaniyami,
poskol'ku sistema scheta ne desyatichnaya. Luchshe pryamo chitat' schetchik
vremeni  sutok BIOS, izmeryat' prodolzhitel'nost' v 1/18 sekundy, a
zatem uzhe perevodit' ee v obychnyj format chch:mm:ss.

100 GOSUB 500              'poluchaem znachenie schetchika
110 START = TOTAL          'sohranyaem nachal'noe znachenie v START
      .
 (dalee idet process, dlitel'nost' kotorogo izmeryaetsya)
      .
300 GOSUB 500              'poluchaem final'noe znachenie
310 TOTAL = TOTAL - START  'podschityvaem chislo impul'sov
320 HOURS = FIX(TOTAL/65520)  'vychislyaem chislo chasov
330 TOTAL = TOTAL - HOURS*65520  'vychitaem chasy iz TOTAL
340 MINUTES = FIX(TOTAL/1092)    'vychislyaem chislo minut
350 TOTAL = TOTAL - MINUTES*1092 'vychitaem minuty iz TOTAL
360 SECONDS = FIX(TOTAL/18.2)    'vychislyaem chislo sekund
370 PRINT HOURS,MINUTES,SECONDS  'pechataem rezul'tat
380 END
      .
      .
500 DEF SEG = 0            'podprogramma chteniya vremeni sutok
510 A = PEEK(&H46C)        'poluchaem mladshij bajt
520 A = PEEK(&H46D)        'poluchaem sleduyushchij bajt
530 A = PEEK(&H46E)        'i eshche odin
540 TOTAL = A + B*256 + C*65535  'podschityvaem rezul'tat v TOTAL
550 RETURN                 'vse sdelano

   Funkciya TIMER v Bejsike  vozvrashchaet  chislo sekund, proshedshih s
momenta, kogda schetchik vremeni sutok byl poslednij raz ustanovlen
v 0. Obychno eto chislo  sekund,  proshedshih  so  vremeni poslednego
vklyucheniya  komp'yutera.   Esli pri starte sistemy  pravil'no  bylo
ustanovleno sistemnoe vremya,  to  TIMER  vozvrashchaet chislo sekund,
proshedshih s polunochi. Prosto napishite N = TIMER.

   Srednij uroven'.

   Preryvanie  1AH  imeet  dve funkcii dlya ustanovki (AH =  1)  i
polucheniya (AH = 0) schetchika  vremeni  sutok.  Dlya chteniya schetchika
nado prosto vypolnit' preryvanie s AH = 0.  Pri vozvrate znachenie
schetchika soderzhitsya v CX:DX, prichem mladshee slovo v CX. AL soder-
zhit 0, esli schetchik ne perehodil cherez granicu 24 chasov s momenta
poslednej ustanovki. Dlya ustanovki schetchika pomestite dva slova v
te  zhe  registry, a v AH - 1.  V privedennom  primere  izmeryayutsya
promezhutki vremeni v  predelah  chasa.  Pri  etom nuzhny tol'ko dva
mladshih  bajta schetchika.  No v etom sluchae neobhodimo  proveryat',
chto ne bylo perehoda cherez granicu, kogda nachal'noe znachenie bylo
bol'she, chem sleduyushchee.


;---v segmente dannyh
OLDCOUNT  DW   0     ;hranim nachal'noe znachenie schetchika
;---poluchaem nachal'noe znachenie schetchika
          MOV  AH,0        ;nomer funkcii
          INT  1AH         ;poluchaem znachenie schetchika
          MOV  OLDCOUNT,DX ;sohranyaem nachal'noe znachenie
           .
   (zdes' idet process, dlitel'nost' kotorogo izmeryaetsya)
           .
;---pozdnee vychislyaem dlitel'nost' processa
          MOV  AH,0        ;nomer funkcii
          INT  1AH         ;poluchaem znachenie schetchika
          MOV  BX,OLDCOUNT ;schityvaem staroe znachenie
          CMP  BX,DX       ;proveryaem na perepolnenie
          JG   ADJUST      ;obrabotka perepolneniya
          SUB  DX,BX       ;inache berem raznost'
          JMP  SHORT FIGURE_TIME  ;i perevodim ee v obychnyj vid
;---obrabotka perepolneniya
ADJUST:   MOV  CX,0FFFFH   ;pomeshchaem v CX maksimal'noe chislo
          SUB  CX,BX       ;vychitaem pervoe znachenie
          ADD  CX,DX       ;dobavlyaem vtoroe znachenie
          MOV  DX,CX       ;rezul'tat hranim v DX
;---procedura perevoda vremeni v obychnyj format
FIGURE_TIME:               ;delim na 18.2 sekundy i t.d.





   Pri  operaciyah v real'nom vremeni programma vypolnyaet instruk-
cii v ukazannyj  moment  vremeni,  a  ne  pri pervoj vozmozhnosti.
Takogo  roda  operacii obychno  associiruyutsya s  robotehnikoj,  no
imeetsya mnozhestvo  drugih  prilozhenij.   Imeetsya  vybor podhoda k
operaciyam  v real'nom vremeni.  Dlya programm, kotorye  ne  dolzhny
nichego delat' v promezhutke mezhdu instrukciyami, trebuyushchimi vremen-
noj privyazki, mozhno prosto periodicheski proveryat' schetchik vremeni
sutok, ozhidaya nastupleniya nuzhnogo  momenta.  Takoj podhod prakti-
cheski svoditsya k naboru pustyh ciklov, opisannyh v [2.1.5].
   Vtoroj  podhod bolee slozhen.  On ispol'zuetsya, kogda programma
postoyanno zanyata kakoj-libo rabotoj, no ona dolzhna v opredelennye
momenty vremeni preryvat' svoi operacii dlya vypolneniya opredelen-
noj zadachi.  V etom sluchae  rasshiryayut preryvanie tajmera, kotoroe
vypolnyaetsya 18.2 raza v sekundu. Kogda eto preryvanie proishodit,
dopolnitel'nyj  kod  proveryaet  novoe  znachenie  schetchika vremeni
sutok  i  esli  nastupil opredelennyj moment  vremeni,  zapuskaet
nuzhnuyu proceduru.  |tot process pokazan na ris.  2-3. Privedennye
zdes'  prostye primery pokazyvayut, kak sozdat' v svoej  programme
budil'nik, kotoryj ustanavlivaetsya  pol'zovatelem i podaet zvuko-
voj  signal, kogda podoshlo vremya.  (Bolee slozhnyj primer  nizkogo
urovnya v [2.2.6]  ispolnyaet  muzyku,  v  to vremya kogda processor
zanyat drugimi delami.)

   Vysokij uroven'.

   Bejsik  obespechivaet  primitivnyj kontrol'  nad  operaciyami  v
real'nom vremeni posredstvom operatora  ON TIMER(n) GOSUB.  Kogda
programma vstrechaet etot operator, to ona nachinaet otschityvat'  n
sekund.  Tem vremenem vypolnenie programmy prodolzhaetsya.  Kogda n
sekund  proshlo, to programma perehodit na podprogrammu,  nachinayu-
shchuyusya s ukazannogo nomera  stroki,  vypolnyaet ee i vozvrashchaet up-
ravlenie  na  to mesto, otkuda byla vyzvana podprogramma.   Posle
etogo otschet snova nachinaetsya s nulya i podprogramma budet vyzvana
snova eshche cherez n sekund.
   ON  TIMER ne budet funkcionirovat', do teh por poka on ne raz-
reshen operatorom TIMER ON. Operator TIMER OFF zapreshchaet ego rabo-
tu.   V teh sluchayah, kogda otschet vremeni dolzhen prodolzhat'sya, no
perehod na podprogrammu dolzhen  byt'  zaderzhan, nado ispol'zovat'
operator TIMER STOP. V etom sluchae otmechaetsya, chto n sekund prosh-
lo, no perehod na podprogrammu budet vypolenen tol'ko posle togo,
kak vstretitsya operator TIMER ON.
   Poskol'ku  on povtoryaetsya, operator ON TIMER osobenno  polezen
dlya vyvoda na ekran tekushchego vremeni:

100 ON TIMER(60) GOSUB 500   'menyaem pokazaniya chasov kazhdye 60
110 TIMER ON                 'sekund i razreshaem rabotu tajmera
 .
 .
500 LOCATE 1,35:PRINT "TIME: ";LEFT$(TIME$,5)  'pozicioniruem
510 RETURN                   'kursor i pechataem vremya


   Nizkij uroven'.

   BIOS soderzhit  special'noe  pustoe  preryvanie  (1CH), kotoroe
nichego  ne  delaet, poka Vy ne napishite dlya nego proceduru.   Pri
starte  vektor  etogo  preryvaniya  ukazyvaet  na  instrukciyu IRET
(vozvrat  iz preryvaniya); pri ego vyzove proishodit  momental'nyj
vozvrat. No  preryvanie  1CH  interesno  tem,  chto ono vyzyvaetsya
preryvaniem  tajmera BIOS posle togo, kak eto preryvanie obnovilo
znachenie schetchika vremeni sutok.  Mozhno skazat', chto eto apparat-
noe  preryvanie, proishodyashchee avtomaticheski 18.2 raza v  sekundu.
Vy mozhete izmenit' vektor etogo preryvaniya tak, chtoby on ukazyval
na proceduru v Vashej programme.  Posle etogo Vasha procedura budet
vyzyvat'sya 18.2 raza v sekundu.   O tom kak napisat' i ustanovit'
svoyu proceduru obrabotki preryvaniya sm. v [1.2.3].
   Napisannaya  Vami procedura dolzhna prochitat' tol'ko chto modifi-
cirovannoe znachenie schetchika  vremeni  sutok, sravnit' ego s ozhi-
daemym  vremenem,  i vypolnit' to chto trebuetsya, kogda  ozhidaemoe
vremya nakonec nastupit.   Estestvenno, chto kogda vremya eshche ne po-
doshlo,  to procedura prosto vozvrashchaet upravlenie, nichego ne  de-
laya. Takim obrazom, processor ne vypolnyaet lishnej raboty.
   V privedennom primere procedura (ne pokazannaya zdes') zaprashi-
vaet u pol'zovatelya chislo minut (do 60), kotoroe dolzhno projti do
togo, kak razdastsya zvonok  budil'nika.   |to chislo, zapasennoe v
MINUTES,  umnozhaetsya  na 1092 dlya perevoda v ekvivalentnoe  chislo
impul'sov schetchika vremeni  sutok.  Dlya perioda v predelah odnogo
chasa  dostatochno  16  bit - bolee dlinnye periody  trebuyut  bolee
slozhnyh 32-bitovyh operacij.   |to  chislo impul'sov dobavlyaetsya k
mladshemu slovu tekushchego znacheniya schetchika vremeni sutok i zapomi-
naetsya v ALARMCOUNT.
   Zatem vektor preryvaniya 1CH izmenyaetsya takim obrazom, chtoby on
ukazyval na proceduru ALARM. Pomnite, chto kak tol'ko vektor budet
izmenen, ALARM budet  avtomaticheski vyzyvat'sya 18.2 raza v sekun-
du.   Pri vyzove eta procedura chitaet tekushchee  znachenie  schetchika
vremeni sutok cherez preryvanie 1AH i sravnivaet s ALARMCOUNT. Pri
sovpadenii etih velichin vyzyvaetsya procedura BEEP (takzhe ne poka-
zannaya zdes' - sm.  [2.2.4]),  kotoraya vydaet zvukovoj signal.  V
protivnom  sluchae  proishodit vozvrat.  Obychnyj kod  vozvrata  iz
apparatnyh preryvanij (MOV AH,20H / OUT 20H,AL) vklyuchat' v proce-
duru  ne  nuzhno, tak kak on budet v preryvanii  tajmera.   Bud'te
vnimatel'ny i ne zabud'te sohranit' izmenyaemye registry.

;---v segmente dannyh
   MINUTES     DW    0     ;hranit chislo minut do zvonka
   ALARMCOUNT  DW    0     ;hranit schetchik vremeni dlya zvonka

;---ustanovka ozhidaemogo znacheniya schetchika vremeni sutok
   CALL  REQUEST_MINUTES   ;zapros chisla minut do zvonka
   MOV   AX,MINUTES        ;peresylka v AX
   MOV   BX,1092           ;chislo impul'sov schetchika v minute
   MUL   BX                ;umnozhaem - rezul'tat v AX
   ;poluchaem tekushchee znachenie schetchika
   MOV   AH,0              ;nomer funkcii chteniya schetchika
   INT   1AH               ;chitaem znachenie, mladshij bajt v DX
   ;skladyvaem oba znacheniya
   ADD   AX,DX             ;
   MOV   ALARMCOUNT,AX     ;poluchaem nuzhnoe znachenie schetchika


;---zamenyaem vektor pustogo preryvaniya
   PUSH  DS                ;sohranyaem segment dannyh
   MOV   AX,SEG ALARM      ;berem segment procedury ALARM
   MOV   DS,AX             ;pomeshchaem ego v DS
   MOV   DX,OFFSET ALARM   ;berem smeshchenie procedury
   MOV   AL,1CH            ;nomer izmenyaemogo vektora
   MOV   AH,25H            ;funkciya izmeneniya vektora
   INT   21H               ;menyaem vektor
   POP   DS                ;vosstanavlivaem segment dannyh
;
;---dal'she prodolzhaetsya programma
;
;---v konce programmy vozvrashchaem vektor preryvaniya
   MOV   DX,0FF53H         ;original'nye znacheniya dlya
   MOV   AX,0F000H         ;preryvaniya 1CH
   MOV   DS,AX             ;pomeshchaem segment v DS
   MOV   AL,1CH            ;nomer izmenyaemogo vektora
   MOV   AH,25H            ;nomer funkcii
   INT   21H               ;vosstanavlivaem vektor

;---procedura vydachi zvukovogo signala
ALARM    PROC FAR          ;sozdaem dlinnuyu proceduru
         PUSH AX           ;sohranyaem izmenyaemye registry
         PUSH CX           ;
         PUSH DX           ;
;---chitaem schetchik vremeni sutok
         MOV  AH,0         ;nomer funkcii chteniya schetchika
         INT  1AH          ;chitaem znachenie schetchika
;---sravnivaem s trebuemym znacheniem
         MOV  CX,ALARMCOUNT   ;berem trebuemoe znachenie
         CMP  DX,CX        ;sravnivaem s tekushchim
         JNE  NOT_YET      ;esli neravny, to na vyhod
;---vydaem zvukovoj signal, esli znacheniya sovpali
         CALL BEEP         ;eta procedura ne pokazana
;---inache vozvrashchaemsya iz preryvaniya
NOT_YET: POP  DX           ;vosstanavlivaem registry
         POP  CX           ;
         POP  AX           ;
         IRET              ;vozvrat iz preryvaniya
ALARM    ENDP              ;konec procedury





   Dlya  generacii  posledovatel'nosti sluchajnyh  chisel  trebuyutsya
slozhnye matematicheskie manipulyacii. No inogda programme v oprede-
lennyj moment trebuetsya tol'ko odno sluchajnoe chislo.  V etom slu-
chae sluchajnoe chislo mozhet byt' polucheno  prosto chteniem iz kanala
mikroshemy tajmera.  Bejsik ispol'zuet eto chislo v kachestve yadra,
po kotoromu generiruetsya sluchajnaya  posledovatel'nost'.  Konechno,
Vy ne mozhete ispol'zovat' ryad posledovatel'no  schitannyh znachenij
v  kachestve  sluchajnoj posledovatel'nosti, tak kak sami  po  sebe
intervaly vremeni mezhdu schityvaniyami budut nesluchajnymi.

100 RANDOMIZE TIMER      'sbros generatora sluchajnyh chisel
110 PRINT RND,RND,RND    'pechat' treh sluchajnyh chisel

v rezul'tate poluchaem:  .7122483  .4695052  .9132487

   Nizkij uroven'.

   Poskol'ku registr  schetchika   kanala  tajmera  perezagruzhaetsya
snova  i  snova dannym chislom (a v promezhutkah idet schet vniz  do
0), vyberite v kachestve  zagruzhaemogo  v  schetchik znacheniya chislo,
ravnoe trebuemomu diapazonu sluchajnyh chisel.  Naprimer, dlya polu-
cheniya sluchajnogo znacheniya chasa dnya zagruzhajte v schetchik 23.
   Luchshe vsego ispol'zovat' rezhim 3 kanala 2 (port 42H) mikroshe-
my  tajmera  [2.1.1].  Snachala ustanovite dlya  schetchika  zhelaemyj
diapazon sluchajnyh chisel (v primere  ispol'zuetsya 10000, chto pri-
vodit k vydache sluchajnogo chisla v diapazone ot 0 do 9999). Zatem,
chtoby poluchit' iz  kanala  sluchajnoe  chislo,  nado podat' komandu
komandnomu  registru mikroshemy tajmera cherez port 43H  perenesti
tekushchee znachenie schetchika  v  registr  "zadvizhki",  dlya chego nado
sbrosit'  bity 4 i 5.  |tot perenos v registr zadvizhki ne  meshaet
prodolzhayushchemusya schetu. Zatem ustanovite oba bita 4 i 5 komandnogo
registra, chtoby processor mog chitat' iz registra zadvizhki.  Posle
etogo dve instrukcii IN dadut  snachala  mladshij,  a zatem starshij
bajt v registre AL. Nakonec, vosstanovite pervonachal'noe znachenie
registra zadvizhki, chtoby schet  prodolzhalsya  v predelah ukazannogo
diapazona vremeni.

;---ustanovka adresov portov
COMMAND_REG  EQU   43H     ;adres komandnogo registra
CHANNEL_2    EQU   42H     ;adres kanala 2
             CALL  SET_COUNT  ;ustanovka diapazona
              .
;---zdes' programma rabotaet, a zatem trebuet sluchajnoe chislo
              .
             CALL  GET_NUMBER ;poluchenie sluchajnogo chisla
              .
              .


;---nachinaem otschet kanala 2
SET_COUNT    PROC
             MOV   AL,10110110B   ;kanal 2, rezhim 2, oba bajta
             OUT   COMMAND_REG,AL ;posylaem v komandnyj registr
             MOV   AX,10000       ;znachenie schetchika
             OUT   CHANNEL_2,AL   ;posylaem mladshij bajt
             MOV   AL,AH          ;peredvigaem starshij bajt v AL
             OUT   CHANNEL_2,AL   ;posylaem starshij bajt
             RET
SET_COUNT    ENDP
;---poluchenie sluchajnogo chisla
READ_NUMBER  PROC
;---peresylaem znachenie schetchika v registr zadvizhki
             MOV   AL,10000110B   ;trebuemaya komanda
             OUT   COMMAND_REG,AL ;posylaem v komandnyj registr
;---chitaem znachenie schetchika
             MOV   AL,10110110B   ;zapros na chtenie/zapis'
             OUT   COMMAND_REG,AL ;posylaem zapros
             IN    AL,CHANNEL_2   ;poluchaem mladshij bajt
             MOV   AH,AL          ;vremenno hranim ego v AH
             IN    AL,CHANNEL_2   ;poluchaem starshij bajt
             CALL  SET_COUNT      ;vosstanavlivaem zadvizhku
             SWAP  AH,AL          ;stavim bajty na mesto
             RET                  ;teper' sluchajnoe chislo v AX
READ_NUMBER  ENDP




   Bejsik osnashchen dostatochno izoshchrennymi sredstvami dlya generacii
zvuka, odnako operacionnaya sistema pozvolyaet tol'ko prosto podat'
zvukovoj signal.  Esli Vy hotite poluchit' kakie-libo slozhnye zvu-
ki, to Vy dolzhny pryamo  programmirovat'  mikroshemu tajmera 8253.
Kanal  2  etoj  mikroshemy pryamo svyazan s  dinamikom  komp'yutera.
Kogda etot kanal programmiruetsya v  rezhime 3, to on posylaet prya-
mougol'nye volny dannoj chastoty. Iz-za prostoty dinamika on sgla-
zhivaet kraya pryamougol'noj volny, poluchaya bolee priyatnuyu dlya sluha
sinusoidal'nuyu  volnu.  K sozhaleniyu, mikroshema 8253 ne mozhet me-
nyat' amplitudu volny, poetomu my ne mozhem menyat' gromkost' zvuka,
izdavaemogo dinamikom.
   Dinamik  imeet  ne odin, a dva vhoda dlya generacii zvuka.   Na
ris. 2-2 v [2.1.1] pokazano, chto krome mikroshemy tajmera, signal
posylaet  takzhe mikroshema interfejsa s periferiej 8255  [1.1.1].
CHastota impul'sov kazhdoj mikroshemy  mozhet byt' izmenena, poetomu
kombiniruya  vozdejstviya  etih dvuh istochnikov my  mozhem  poluchat'
special'nye zvukovye effekty.
   Tol'ko PCjr imeet special'nuyu mikroshemu,  upravlyayushchuyu genera-
torom zvuka. On mozhet odnovremenno vydavat' tri raznyh tona, plyus
shum dlya zvukovyh  effektov.   Gromkost'  kazhdogo  iz treh kanalov
mozhet ustanavlivat'sya nezavisimo.  Drugoj unikal'noj vozmozhnost'yu
PCjr yavlyaetsya to, chto on mozhet  upravlyat' vneshnim istochnikom zvu-
ka, takim kak kassetnyj magnitofon.





   PCjr  snabzhen  4-kanal'nym  generatorom zvuka, v  kotorom  tri
kanala generiruyut tona, a chetvertyj sluzhit dlya generacii shuma dlya
zvukovyh effektov.  Vse chetyre kanala programmiruyutsya nezavisimo,
prichem kazhdyj iz  nih  imeet  svoj  regulyator  gromkosti, a zatem
vyhod so vseh nih ob®edinyaetsya v edinyj zvukovoj signal.  Ispol'-
zuetsya mikroshema kompleksnogo generatora  zvuka TI SN76496N. Ona
imeet  8 registrov - 2 dlya kazhdogo kanala - i vse oni  adresuyutsya
cherez odin port s adresom 0C0H. |tot port sluzhit tol'ko dlya zapi-
si; esli podat' instrukciyu IN, to vsya sistema budet zamorozhena.
   PCjr  imeet  takzhe raz®em dlya vneshnego istochnika  zvuka.   Pri
starte sistemy zvukovoj kanal poluchaet vyhodnoj signal ot mikros-
hemy tajmera 8253. No etot kanal mozhet byt' pereklyuchen na mikros-
hemu generatora zvuka ili lyuboj  iz dvuh vneshnih zvukovyh vhodov.
|to  dostigaetsya izmeneniem bitov 5 i 6 porta B mikroshemy inter-
fejsa s periferiej 8255 (adres porta 61H - sm. [1.1.1]). Znachenie
bitov sleduyushchee:

        Bity 6 i 5          Vybrannaya funkciya

           00               mikroshema tajmera 8253
           01               vhod s kassetnogo magnitofona
           10               vhod kanala vvoda/vyvoda
           11               generator zvuka 76496

Dlya  vybora  istochnika zvuka v BIOS PCjr  dobavlena  funkciya  80H
preryvaniya 1AH. Pomestite v AL nomer koda ot 0 do 3, v sootvetst-
vii s vysheprivedennoj tablicej, i vyzovite funkciyu.  Vozvrashchaemyh
registrov net.  Generator  zvuka  76496  dolzhen ispol'zovat' etot
zvukovoj  kanal, poskol'ku on ne mozhet upravlyat' vnutrennim dina-
mikom PCjr.
   V obshchem sluchae, kogda bajt dannyh posylaetsya generatoru zvuka,
to  bity  4-6 soderzhat kod identifikacii,  soobshchayushchij  kakomu  iz
vos'mi registrov prednaznacheny dannye. |ti kody takie:

        Bity 6-4            Adresuemyj registr

         000                CHastota pervogo tona
         001                Gromkost' pervogo tona
         010                CHastota vtorogo tona
         011                Gromkost' vtorogo tona
         100                CHastota tret'ego tona
         101                Gromkost' tret'ego tona
         110                CHastota chetvertogo tona
         111                Gromkost' chetvertogo tona

   V sluchae registrov chastoty tonov trebuyutsya dva bajta. Znachenie
bitov pri etom sleduyushchee:

   bajt 1: bity 0-3   mladshie 4 bita chastoty
                4-6   kod identifikacii registra
                  7   vsegda raven 1
   bajt 2: bity 0-5   starshie 6 bitov chastoty
                  6   ne ispol'zuetsya
                  7   vsegda raven 0


Dlya ustanovki chastoty tona v registr  posylaetsya 10-bitnoe znache-
nie, kotoroe posle deleniya  na  111  843  daet zhelaemuyu chastotu v
gercah. Takim obrazom, dostupny chastoty, nachinaya s 110 gerc vverh
(111 843/2^10).  Kak tol'ko registr inicializirovan (i sootvetst-
venno  ustanovlen port B mikroshemy 8255), nemedlenno  nachinaetsya
zvukovoj signal i prodolzhaetsya do teh por, poka on ne budet prek-
rashchen.   Ne obyazatel'no dlya izmeneniya chastoty posylat' novye  dva
bajta.  Esli poslan tol'ko vtoroj bajt (starshie 6 bitov chastoty),
to  on avtomaticheski zamenyaet sootvetstvuyushchie dannye v kanale,  k
kotoromu byla  poslednyaya  adresaciya.   |ta  vozmozhnost' pozvolyaet
plavno var'irovat' chastotu.
   Generatoru  shuma dlya programmirovaniya nuzhen tol'ko odin  bajt.
Znachenie bitov dlya nego sleduyushchee:

   bity 0-1     plotnost' shuma
          2     kachestvo shuma
          3     ne ispol'zuetsya
        4-6     kod identifikacii registra
          7     vsegda ustanovlen v 1

Kachestvo shuma ustanavlivaetsya na  belyj shum (postoyannoe shipenie),
kogda  bit 2 raven 1 i na periodicheskij shum (volny zvuka),  kogda
bit 2 raven 0. Plotnost' zvuka uvelichivaetsya pri uvelichenii bitov
0-1  ot 00B do 10B; kogda oni ustanovleny v 11B, to zvuk menyaetsya
v zavisimosti ot vyhodnogo tona kanala 3.
   Gromkost' kazhdogo iz chetyreh  kanalov  izmenyaetsya  oslableniem
osnovnogo signala. Dlya etoj ustanovki trebuetsya tol'ko odin bajt.
Znachenie ego bitov sleduyushchee:

   bity 0-3     oslablenie signala
        4-6     kod identifikacii registra
          7     vsegda ustanovlen v 1

Kogda vse 4 bita dannyh ravny 0, to  gromkost' maksimal'na. Kogda
vse  oni  ravny 1, to zvuk polnost'yu podavlyaetsya.  Dlya  polucheniya
zvuka promezhutochnoj gromkosti mozhet  byt' ispol'zovana lyubaya kom-
binaciya bitov.  Bit 0 oslablyaet zvuk na 2 Db (decibella), bit 1 -
na 4 Db, bit 2 - na 8 Db i bit 3 - na 16 Db.  Maksimal'noe oslab-
lenie ravno 28 Db.





   |tot podrazdel ob®yasnyaet kak proizvodit' zvuk, kogda komp'yuter
ne zanyat nichem drugim; v [2.2.3]  pokazano kak eto sdelat', kogda
proizvodyatsya  drugie dejstviya.  Zabavno, no dlya programmistov  na
assemblere poslednee proshche.  Dlya  etogo dostatochno zaprogrammiro-
vat'  mikroshemu  tajmera  8253, kotoraya rabotaet  nezavisimo  ot
processora.  V privedennom zdes' metode processor neposredstvenno
upravlyaet dinamikom, poetomu programme prihoditsya vypolnyat' rabo-
tu, kotoruyu mozhet vypolnyat' mikroshema tajmera.  Hotya etot sposob
bolee  truden, no on dopuskaet sushchestvenno bol'shij  kontrol'  nad
dinamikom i  sozdanie  bol'shinstva  special'nyh zvukovyh effektov
[2.2.8] osnovyvaetsya na nem.

   Vysokij uroven'.

   Operator Bejsika SOUND ispol'zuetsya dlya generacii tona v shiro-
kom diapazone chastot i dlitel'nostej. CHastota daetsya v gercah (ot
37  do 32767), a dlitel'nost' v impul'sah schetchika vremeni  sutok
BIOS (ot 0 do 65535), prichem v  sekundu proishodit 18.2 impul'sa.
SOUND  440,91  vosproizvodit notu A v techenie 5 sekund  (5*18.2).
CHastoty pervoj oktavy, nachinaya s noty C(do) takovy:

                 C(do)              523.3
                 D(re)              587.3
                 E(mi)              659.3
                 F(fa)              698.5
                 G(sol')            784.0
                 A(lya)              880.0
                 B(si)              987.7

CHastoty  na oktavu vyshe mozhno poluchit', udvaivaya eti znacheniya, na
dve oktavy vyshe - eshche raz udvaivaya  chastoty.  I naoborot, chastoty
na oktavu nizhe ravny priblizitel'no polovine etih znachenij (horo-
sho nastroennoe pianino tochno ne  sleduet  arifmeticheskim interva-
lam).
   Blagodarya svoemu generatoru zvuka [2.2.1] PCjr mozhet ispol'zo-
vat'  operator  SOUND dlya treh nezavisimyh kanalov zvuka,  prichem
mozhet upravlyat'sya gromkost' kazhdogo  iz nih. V etom sluchae format
operatora:  SOUND chastota, dlitel'nost', gromkost', kanal.  Grom-
kost' mozhet menyat'sya ot 0  do  15,  po  umolchaniyu 8. Nomer kanala
mozhet  menyat'sya ot 0 do 2, po umolchaniyu 0.  Poskol'ku PCjr  mozhet
ispol'zovat' vozmozhnosti mnogogolosiya i kontrolya zvuka tol'ko dlya
vneshnego  dinamika, to nado snachala razreshit' etot dinamik.   |to
delaetsya s pomoshch'yu operatora SOUND  ON.  SOUND OFF peredaet kont-
rol'  vnutrennemu dinamiku.  CHtoby sygrat' akkord D-minor (re-mi-
nor) (D-F-A) s maloj gromkost'yu, napishite:

100 SOUND ON             'razreshenie vneshnego dinamika
110 SOUND 587,50,3,0     'nota re
120 SOUND 699,50,3,1     'nota fa
130 SOUND 880,50,3,1     'nota lya


   Nizkij uroven'.

   Generaciya zvuka s  pomoshch'yu  adaptera  interfejsa  s periferiej
8255  sostoit vo vklyuchenii i vyklyuchenii s zhelaemoj chastotoj  bita
porta B, kotoryj svyazan s dinamikom  (bit 1).  Port B imeet adres
61H (hotya AT ne imeet mikroshemy interfejsa s periferiej 8255 kak
takovoj, on ispol'zuet dlya etoj  celi tot zhe adres porta i tot zhe
bit).   Esli  programma pereklyuchaet znachenie  bita s  maksimal'no
vozmozhnoj chastotoj, to chastota slishkom vysokaya, chtoby byt' polez-
noj.   Poetomu  mezhdu dvumya pereklyucheniyami nado vstavlyat'  pustoj
cikl.  Pomnite, chto bit 0  porta  B  upravlyaet  vorotami kanala 2
mikroshemy  tajmera, kotoryj v svoyu ochered'  svyazan s  dinamikom.
Poetomu etot bit  dolzhen  byt'  sbroshen,  otsoedinyayas'  ot kanala
tajmera. Na ris. 2-4 pokazano kak etot metod ustanavlivaet chasto-
tu zvuka.
   V sleduyushchem primere vvedeny dve peremennye. Odna, oboznachennaya
"FREQUENCY",  ispol'zuetsya  v  kachestve  schetchika  v pustom cikle
mezhdu dejstviyami vklyucheniya i vyklyucheniya.  CHem men'she ee znachenie,
tem bystree proishodit izmenenie bita i tem bol'she chastota. Pere-
mennaya  zhe "NUMBER_CYCLES" ustanavlivaet prodolzhitel'nost'  tona.
Ona govorit skol'ko raz dolzhen byt'  povtoren process vklyucheniya i
vyklyucheniya. CHem bol'she eto chislo, tem dol'she zvuchit dannyj zvuk.
   Otmetim,  chto dlya etoj procedury apparatnye preryvaniya  dolzhny
byt'  zapreshcheny.   Prichina etogo v tom,  chto  preryvanie  tajmera
proishodit s takoj chastotoj i  regulyarnost'yu  (18.2 raza v sekun-
du),  chto ono budet sushchestvenno vliyat' na chastotu.  Imejte vvidu,
chto poka preryvaniya  zapreshcheny,  schetchik  vremeni  sutok  BIOS ne
budet  rabotat'.  Esli zatem prochitat' ego znachenie, to ono budet
otlichat'sya na nekotoruyu  velichinu  ot real'nogo, do teh por, poka
ne budet sdelano sootvetstvuyushchee izmenenie.

NUMBER_CYCLES  EQU   1000
FREQUENCY      EQU   300
PORT_B         EQU   61H
               CLI                 ;zapret preryvanij
               MOV   DX,NUMBER_CYCLES  ;dlitel'nost' tona v DX
               IN    AL,PORT_B     ;poluchaem znachenie iz porta B
               AND   AL,11111110B  ;otklyuchaem dinamik ot tajmera
NEXT_CYCLE:    OR    AL,00000010B  ;vklyuchaem dinamik
               OUT   PORT_B,AL     ;posylaem komandu v port B
               MOV   CX,FREQUENCY  ;zaderzhka na pol-cikla v CX
FIRST_HALF:    LOOP  FIRST_HALF    ;delaem zaderzhku
               AND   AL,11111101B  ;vyklyuchaem dinamik
               OUT   PORT_B,AL     ;posylaem komandu v port B
               MOV   CX,FREQUENCY  ;zaderzhka na pol-cikla v CX
SECOND_HALF:   LOOP  SECOND_HALF   ;delaem zaderzhku
               DEC   DX            ;vychitaem edinicu iz schetchika
               JNZ   NEXT_CYCLE    ;esli 0, to nado konchat'
               STI                 ;razreshaem preryvaniya





   Dlya  programmistov na Bejsike razlichie mezhdu etim i predydushchim
razdelom sovershenno nesushchestvenno.  No programmisty na assemblere
dolzhny ispol'zovat' sovershenno drugoj metod. Poskol'ku mikroshema
tajmera 8253 rabotaet  nezavisimo  ot processora, to ochen' prosto
generirovat'  zvuk,  kotoryj izdaetsya odnovremenno s  vypolneniem
drugih operacij.  Vy dolzhny prosto zaprogrammirovat' kanal 2 etoj
mikroshemy  dlya generacii opredelennoj chastoty, a zatem pereprog-
rammirovat' mikroshemu dlya vyklyucheniya zvuka.

   Vysokij uroven'.

   Operator SOUND v Bejsike ne pozvolyaet generirovat' zvuk odnov-
remenno  s drugimi dejstviyami, no operator PLAY - pozvolyaet  esli
emu eto zadat'. Za operatorom PLAY dolzhna sledovat' stroka, koto-
raya soobshchaet kakie noty dolny byt' sygrany, kakoj dlitel'nosti, a
takzhe drugie harakteristiki.  Detali komandnoj stroki PLAY obsuzh-
dayutsya v [2.2.5]. Esli stroka soderzhit bukvy MB (fonovaya muzyka),
to stroka pomeshchaetsya v  special'nyj  bufer i vypolnyaetsya odnovre-
menno s drugimi programmnymi dejstviyami.  Naprotiv, MF (muzyka na
perednem plane)  ostanavlivaet  vse  programmnye  operacii do teh
por,  poka vsya stroka ne budet ispolnena.  Vot kak ispolnit' odnu
notu A (lya) v fonovom rezhime:

100 PLAY "MB A"    'ispolnyaetsya nota lya...
110 ......         'i sleduyushchie operatory programmy

   Otmetim, chto v fonovom rezhime, operator X = PLAY(0) vozvrashchaet
chislo  not  (do 32), kotoroe ostalos' sygrat'.  V  mnogokanal'nom
rezhime na PCjr  vozvrashchaetsya  chislo  not  v bufere dannogo kanala
(0-2), nomer kotorogo ukazan v skobkah.

   Nizkij uroven'.

   Prosto  poshlite  schetchik v kanal 2, kak  ob®yasneno v  [2.1.1].
Mikroshema  dolzhna  byt'  predvaritel'no  razreshena  cherez port B
mikroshemy  interfejsa s periferiej 8255 (adres 61H).   Vychislite
trebuemoe znachenie schetchika dlya zadvizhki, razdeliv 1.19 millionov
na  trebuemuyu  chastotu v gercah.  Zvuk budet prodolzhat'sya do  teh
por, poka ne budut  zakryty  vorota  kanala  2. Poetomu Vy dolzhny
sbrosit'  bit 1 porta B v 0, inache zvuk budet prodolzhat'sya besko-
nechno i mozhet byt' prekrashchen tol'ko perezagruzkoj komp'yutera. Dlya
tochnogo regulirovaniya dlitel'nosti zvuka mozhno ispol'zovat' schet-
chik vremeni sutok BIOS, kak  ukazano  v [2.1.6]. V dannom primere
generiruetsya  chastota 440 gerc.  Zvuk prekrashchaetsya posle  nazhatiya
lyuboj klavishi na klaviature.

;---rareshenie kanala 2 ustanovkoj porta B mikroshemy 8255
PORT_B     EQU  61H           ;ustanovka adresa porta B
           IN   AL,PORT_B     ;chtenie ego znacheniya
           OR   AL,3          ;ustanovka dvuh mladshih bitov
           OUT  PORT_B,AL     ;posylaem bajt v port B


;---ustanovka registrov vvoda/vyvoda
COMMAND_REG  EQU  43H         ;adres komandnogo registra
CHANNEL_2    EQU  42H         ;adres kanala 2
             MOV  AL,10110110B    ;cepochka bitov dlya kanala 2
             OUT  COMMAND_REG,AL  ;zasylka v komandnyj registr
;---zasylka schetchika v zadvizhku
           MOV  AX,2705       ;schetchik = 1190000/440
           OUT  CHANNEL_2,AL  ;posylaem mladshij bajt
           MOV  AL,AH         ;sdvigaem mladshij bajt v AL
           OUT  CHANNEL_2,AL  ;posylaem starshij bajt
;---zhdem nazhatiya klavishi
           MOV  AH,1          ;nomer funkcii preryvaniya 21H
           INT  21H           ;vyzyvaem preryvanie
;---vyklyuchenie zvuka
           IN   AL,PORT_B     ;poluchaem bajt iz porta B
           AND  AL,11111100B  ;sbrasyvaem dva mladshih bita
           OUT  PORT_B,AL     ;posylaem bajt obratno





   Nekotorym  programmam trebuetsya nabor predosteregayushchih gudkov.
Ih legko sozdavat' na Bejsike, no operacionnaya sistema ne obespe-
chivaet  funkciyu gudka, kak takovuyu, i tol'ko  kosvenno  pozvolyaet
poluchat' dostup k gudku,  kotoryj  Vy slyshite pri starte sistemy.
Dlya  izmeneniya  tona vsya procedura generacii  zvuka  dolzhna  byt'
zaprogrammirovana na nizkom  urovne.   Dlya togo chtoby gudok soot-
vetstvoval  podavaemomu im signalu neobhodimo proyavit'  voobrazhe-
nie. Dlya predskazaniya blizkoj  opasnosti  sozdajte nabor ponizhayu-
shchihsya  tonov [2.2.7] ili, esli printer vklyuchen,  cheredujte  gudki
dinamika komp'yutera i printera (vyvod koda ASCII 7 na printer).

   Vysokij uroven'.

   V Bejsike prosto  napishite  BEEP.   Vot  kusochek koda, kotoryj
reagiruet na veroyatnuyu oshibku gudkom i zaprosom:

100 INPUT "Enter your age",AGE             'zapros vozrasta
110 IF AGE > 100 THEN BEEP:PRINT"Are you really over 100?"

   Dlya  gudkov  drugoj  chastoty i  prodolzhitel'nosti  ispol'zujte
operator SOUND.  Ego  forma:  SOUND  chastota,  dlitel'nost' , gde
chastota  daetsya v gercah (3000 - seredina diapazona), a  dlitel'-
nost' daetsya v vosemnadcatyh  dolyah  sekundy.  SOUND 3000,18 daet
gudok dlitel'nost'yu okolo odnoj sekundy. V nizheprivedennom prime-
re dinamik bystro perehodit ot vysokogo tona k nizkomu i obratno,
raspugivaya vse zhivoe v blizhajshej okrestnosti.

100 FOR N = 1 TO 200   'ustanovka chisla povtorenij
110 SOUND 500,1        'zvuk nizkoj chastoty na 1 sekundu
120 SOUND 5000,1       'zvuk vysokoj chastoty na 1 sekundu
130 NEXT               'povtor

   Srednij uroven'.

   Operacionnaya sistema ne predostavlyaet  special'noj funkcii dlya
generacii zvuka. No Vy mozhete vyzvat' znakomyj gudok prosto poda-
vaya kod ASCII 7 na standartnoe ustrojstvo vyvoda (t.e. terminal),
ispol'zuya  odnu iz funkcij DOS ili BIOS.  Kod ASCII 7 interpreti-
ruetsya kak upravlyayushchij simvol "zvonok"  i on ne risuetsya na ekra-
ne. Proshche vsego ispol'zovat' funkciyu 2 preryvaniya 21H:

   MOV  AH,2     ;funkciya vyvoda simvola na ekran
   MOV  DL,7     ;posylaem kod ASCII 7
   INT  21H      ;dinamik gudit

   Nizkij uroven'.

   Dlya  prostogo gudka luchshe vsego podhodit metod, osnovannyj  na
ispol'zovanii mikroshemy  interfejsa  s  periferiej 8255 [1.1.1].
Nizhe priveden primer, kotoryj prakticheski povtoryaet gudok,  koto-
ryj Vy slyshite pri starte sistemy.


;---gudok dinamika
            MOV  DX,800          ;schetchik chisla ciklov
            IN   AL,61H          ;chitaem port B 8255
            AND  AL,0FEH         ;vyklyuchaem bit tajmera 8253
NEXTCYCLE:  OR   AL,2            ;vklyuchaem bit dinamika
            OUT  61H,AL          ;posylaem bajt v port B
            MOV  CX,150          ;dlitel'nost' pervoj poloviny
CYCLEUP:    LOOP CYCLEUP         ;zaderzhka poka signal vysokij
            AND  AL,0FDH         ;vyklyuchaem bit dinamika
            OUT  61H,AL          ;posylaem bajt v port B
CYCLEDOWN:  LOOP CYCLEDOWN       ;zaderzhka poka signal nizkij
            DEC  DX              ;umen'shaem schetchik ciklov
            JNZ  NEXTCYCLE       ;povtoryaem cikl poka DX ne 0





   V  etom  podrazdele pokazano kak generirovat' cepochku  zvukov,
kogda komp'yuter nichem drugim ne zanyat; v sleduyushchem budet pokazano
kak vypolnit' tu zhe zadachu, kogda komp'yuter zanyat drugoj rabotoj.
Kogda komp'yuter nichem drugim ne zanyat,  to mozhno vyvodit' melodiyu
ili proizvodit' special'nye zvukovye effekty; kogda zhe  komp'yuter
zanyat drugoj rabotoj, to nel'zya proizvodit' zvukovye effekty.
   Sozdanie zvukovyh strok yavlyaetsya odnoj iz moshchnejshih vozmozhnos-
tej, predostavlyaemyh Bejsikom.  Postroenie zhe strok zvukov v  as-
semblere trebuet bol'shoj raboty.  Mozhet byt' ispol'zovan lyuboj iz
dvuh  metodov generacii zvuka, predlozhennyh v [2.2.2] i  [2.2.3].
Dlya oboih metodov nado  prosto  generirovat'  odin  ton v techenii
zadannogo vremeni, zatem sleduyushchij i t.d.  Kazhdaya zvukovaya stroka
formiruetsya iz dvuh strok dannyh, odna iz kotoryh soderzhit chasto-
ty  posledovatel'nyh tonov, a drugaya hranit ih dlitel'nosti  (pri
uslovii, chto trebuyutsya raznye  dlitel'nosti).   Prodolzhitel'nost'
zvuchaniya  opredelyaetsya  s ispol'zovaniem schetchika  vremeni  sutok
BIOS [2.1.6].

   Vysokij uroven'.

   Opreator Bejsika PLAY predostavlyaet bol'shie vozmozhnosti.  Ope-
rator  soprovozhdaetsya strokoj not, peremeshannyh s  informaciej  o
tom, kak eti noty dolzhny byt' ispolneny. Noty zapisyvayutsya bukva-
mi A - G i posleduyushchimi znakami dlya diezov i bemolej. Diezy oboz-
nachayutsya znakami # ili +, a  bemoli  minusom (-).  Operatory PLAY
"CC#D" i PLAY "CD-D" ekvivalentny, no nel'zya ispol'zovat' diezy i
bemoli dlya oboznacheniya belyh  klavish.   Vtoroj sposob zadaniya not
sostoit  v vychislenii kodovogo nomera ot 0 do 84, prichem 0  soot-
vetstvuet otsutstviyu zvuchaniya,  a  chisla ot 1 do 84 sootvetstvuyut
84 vozmozhnym notam semi oktav, nachinaya snizu. Nomeru dolzhna pred-
shestvovat' bukva N: PLAY "N3N72N44".
   Dopustimyj diapazon -  sem'  oktav,  vnutri  kazhdoj mogut byt'
noty ot C(do) do B(si).  Oktavy pronumerovany ot 0 do 6 i nota do
pervoj oktavy sootvetstvuet  oktave  3. Tekushchaya oktava mozhet byt'
izmenena  v  lyuboj moment, za schet vstavki v stroku bukvy  O,  za
kotoroj sleduet nomer oktavy.  Esli  ne bylo nachal'noj ustanovki,
to  ispol'zuetsya oktava 4.  Operator PLAY "O3CO4CO5CO6C"  vyvodit
noty do posledovatel'nyh oktav  vverh.   Drugoj  sposob izmeneniya
oktavy  sostoit vo vklyuchenii v stroku simvolov > ili  <,  kotorye
pereklyuchayut ton vverh i vniz na oktavu, sootvetstvenno.  Operator
PLAY "O3C>C>C>C" privodit k tomu zhe rezul'tatu, chto i predydushchij.
   Dlitel'nost' ispolneniya not takzhe mozhet byt' izmenena za  schet
vstavki kodovogo nomera, kotoromu predshestvuet bukva L.  Vse pos-
leduyushchie noty budut ispolnyat'sya s etoj dlitel'nost'yu do teh  por,
poka ne vstretitsya drugoj kod dliny.  Kod - eto chislo ot 1 do 64,
prichem  1 sootvetstvuet celoj note, a 64 - 1/64.  Zapis' L4 soot-
vetstvuet chetverti.  Temp s kotorym ispolnyayutsya noty reguliruetsya
kodom tempa, kotoryj sostoit iz bukvy T, za kotoroj sleduet chislo
ot 32 do 255, dayushchee chislo chetvertej, ispolnyaemyh v minutu.  Esli
eti parametry ne ukazany, to po umolchaniyu beretsya dlitel'nost' L4
i temp 120.  Dlya  izmeneniya  dlitel'nosti  tol'ko odnoj noty nado
pomestit' znachenie dliny posle noty i bez bukvy L.  Operator PLAY


"L4CDE16FG" ispolnit E kak shestnadcatuyu, a vse ostal'nye noty kak
chetverti.  Dlitel'nost' pauz beretsya takoj zhe, kak i dlitel'nost'
not.  Pomestite nomer ot 1 do 64 posle bukvy P dlya pauzy.  P1 de-
laet  pauzu intervalom v celuyu, a P64 - v 1/64.  Pomeshchenie  tochki
posle noty imeet tot zhe effekt,  kakoj  on  imeet v obychnoj muzy-
kal'noj  notacii:  dlitel'nost'  noty  uvelichivaetsya  napolovinu.
Vtoraya tochka prodolzhit dlitel'nost' eshche napolovinu.
   Po umolchaniyu noty igrayutsya 7/8 ukazannoj  dlitel'nosti.  CHtoby
oni ispolnyalis' polnuyu dlitel'nost' (legato), pomestite v  stroku
ML. CHtoby oni ispolnyalis' 3/4  dlitel'nosti (stakkato), pomestite
v stroku MS. CHtoby vernut'sya k normal'nomu stilyu nado ukazat' MN.
   Obychno,  vsya prochaya deyatel'nost' programmy prekrashchaetsya do teh
por, poka ne budet  sygrana  stroka.  Dlya  togo chtoby vypolnyalis'
operatory,  sleduyushchie za operatorom PLAY, a stroka ispolnyalas'  v
fonovom rezhime, pomestite v  stroku  MB.  Dlya vosstanovleniya nor-
mal'noj situacii napishite MF.
   Nakonec,  operator  PLAY pozvolyaet ispolnyat' podstroki  vnutri
dlinnoj stroki.  Imeetsya  v  vidu,  chto  chast' ispolnyaemoj stroki
mozhet byt' vvedena kak obychnaya strokovaya peremennaya, a zatem  eta
peremennaya mozhet byt' vyzvana iz stroki sformirovannoj v operato-
re  PLAY.   Naprimer,  esli S$ =  "EEEEE",  to v  operatore  PLAY
"CDXS$;FG" nota E budet povtorena 5 raz. Otmetim, chto imeni pere-
mennoj dolzhna predshestvovat' bukva X, a za imenem sledovat' tochka
s zapyatoj (;).  (Dlya  kompiliruemyh  programm  primenyaetsya drugoj
metod, ispol'zuyushchij peremennuyu VARPTR$ - detali sm. v rukovodstve
po Bejsiku).
   V privedennom  primere  ispolnyaetsya  znakomyj  boj  dedushkinyh
chasov.  V stroke snachala ustanavlivaetsya stil' ispolneniya legato,
zatem temp i nachal'naya oktava,  i, nakonec, chetyre noty, pauza, i
te zhe samye chetyre noty, no v obratnom poryadke.  Probely v stroke
vklyucheny isklyuchitel'no dlya udobstva programmista - Bejsik ignori-
ruet ih.

   100 PLAY "ML T40 O3 ECD<G P32 G>DEC"

   Blagodarya nalichiyu generatora zvuka PCjr dobavlyaet k  operatoru
PLAY dve vozmozhnosti. Vo-pervyh, dopuskaetsya parametr V, ustanav-
livayushchij  gromkost'.  Vyrazhenie V5 ustanavlivaet  (ili  izmenyaet)
gromkost' na uroven' 5. Dopustimyj diapazon ot 0 do 15, prichem po
umolchaniyu  beretsya 8.  0 polnost'yu podavlyaet zvuk.  Vo-vtoryh,  s
pomoshch'yu operatora PLAY mozhno  odnovremenno ispolnyat' tri zvukovyh
stroki.  Pomestite vse tri stroki v odnu programmnuyu stroku, raz-
delyaya ih zapyatymi.  Dlya togo chtoby imet' vozmozhnost' ispol'zovat'
eti  special'nye  svojstva,  Vy dolzhny  predvaritel'no  razreshit'
vneshnij dinamik s pomoshch'yu operatora SOUND ON.

   100 SOUND ON
   110 PLAY "...........","..........","............"

   Nizkij uroven'.

   V primere dlya generacii zvuka ispol'zuetsya  mikroshema tajmera
8253.   Zdes' prosto ispolnyayutsya 8 not, no nebol'shaya  modifikaciya
mozhet sil'no rasshirit'  vozmozhnosti  etoj procedury.  Imeetsya tri
stroki dannyh. Pervaya ustanavlivaet dlitel'nost' kazhdoj noty, kak
kratnoe proizvol'nogo perioda  zaderzhki  (izmenyaya etot period za-


derzhki,  mozhno  izmenyat' temp).  Vtoraya stroka  soderzhit  chastoty
kazhdoj iz 8 not;  eti  znacheniya  dolzhny  byt'  pomeshcheny v registr
zadvizhki  kanala 2 mikroshemy 8253 dlya ispolneniya zhelaemyh tonov.
Tret'ya stroka soderzhit melodiyu v vide  kodovyh nomerov ot 1 do 8,
kotorye  sootvetstvuyut  vos'mi chastotam.  |ta stroka  zavershaetsya
kodom 0FFH, kotoryj  sluzhit  priznakom  konca  melodii. Procedura
prosto  chitaet  ocherednuyu notu melodii,  nahodit  sootvetstvuyushchuyu
chastotu i pomeshchaet ee v kanal 2. Zatem dlitel'nost' dlya etoj noty
pomeshchaetsya  v schetchik cikla zaderzhki, kotoryj ispol'zuet  schetchik
vremeni sutok, a kogda zaderzhka  konchaetsya,  to perehodim k obra-
botke sleduyushchej noty. Na ris. 2-5 pokazana rabota etoj procedury.

;---v segmente dannyh
BEAT        DB   10,9,8,7,6,5,4,3,2    ;dlitel'nost' not
FREQUENCY   DW   2280,2031,1809,1709   ;tablica chastot
            DW   1521,1353,1207,1139   ;
MELODY      DB   1,2,3,4,5,6,7,8,0FFH  ;nomer chastoty noty

;---inicializaciya
PORT_B      EQU  61H
COMMAND_REG EQU  43H
LATCH2      EQU  42H
            IN   AL,PORT_B      ;poluchaem tekushchij status
            OR   AL,00000011B   ;razreshaem dinamik i tajmer
            OUT  PORT_B,AL      ;zamenyaem bajt
            MOV  SI,0           ;inicializiruem ukazatel'
            MOV  AL,0B6H        ;ustanovka dlya kanala 2
            OUT  COMMAND_REG,AL ;posylaem v komandnyj registr
;---smotrim notu, poluchaem ee chastotu i pomeshchaem v kanal 2
NEXT_NOTE:  LEA  BX,MELODY      ;berem smeshchenie dlya melodii
            MOV  AL,[BX][SI]    ;berem kod n-noj noty stroki
            CMP  AL,0FFH        ;proverka na konec stroki
            JE   NO_MORE        ;esli konec, to na vyhod
            CBW                 ;perevodim v slovo
   ;poluchenie chastoty
            MOV  BX,OFFSET FREQUENCY  ;smeshchenie tablicy chastot
            DEC  AX             ;nachinaem otschet s 0
            SHL  AX,1           ;umnozhaem na 2, t.k. slova
            MOV  DI,AX          ;adresuem cherez DI
            MOV  DX,[BX][DI]    ;poluchaem chastotu iz tablicy
   ;nachinaem ispolnenie noty
            MOV  AL,DL          ;gotovim mladshij bajt chastoty
            OUT  LATCH2,AL      ;posylaem ego
            MOV  AL,DH          ;gotovim starshij bajt chastoty
            OUT  LATCH2,AL      ;posylaem ego
;---sozdanie cmkla zaderzhki
            MOV  AH,0           ;nomer funkcii chteniya schetchika
            INT  1AH            ;poluchaem znachenie schetchika
            MOV  BX,OFFSET BEAT ;smeshchenie tablicy dlin
            MOV  CL,[BX][SI]    ;berem dlinu ocherednoj noty
            MOV  CH,0           ;
            MOV  BX,DX          ;berem mladshee slovo schetchika
            ADD  BX,CX          ;opredelyaem moment okonchaniya


STILL_SOUND: INT 1AH            ;berem znachenie schetchika
            CMP  DX,BX          ;sravnivaem s okonchaniem
            JNE  STILL_SOUND    ;neravny - prodolzhaem zvuk
            INC  SI             ;perehodim k sleduyushchej note
            JMP  NEXT_NOTE      ;
;---zavershenie
NO_MORE:    IN   AL,PORT_B      ;poluchaem status porta B
            AND  AL,0FCH        ;vyklyuchaem dinamik
            OUT  61H,AL         ;zamenyaem bajt





   Hotya v Bejsike eto  delaetsya  ochen'  prosto, na samom dele eto
netrivial'nyj tryuk programmirovaniya v real'nom vremeni. Dlya reshe-
niya etoj zadachi nuzhno  ispol'zovat' generaciyu zvuka cherez mikros-
hemu  8253  [2.2.3], tak kak metod, ispol'zuyushchij mikroshemu  8255
[2.2.2], zanimaet processor. Sootvetstvenno, tol'ko stroki chistyh
muzykal'nyh  tonov  mogut proizvodit'sya takim  metodom -  vsyakogo
roda zvukovye effekty pri etom nedostupny. Osnovnaya tehnika prog-
rammirovaniya  v real'nom vremeni pokazana v [2.1.7].   Programmy,
rabotayushchie v real'nom vremeni,  modificiruyut  preryvanie tajmera,
kotoroe  ostanavlivaet processor 18.2 raz v sekundu, chtoby  izme-
nit' pokazanie schetchika vremeni sutok.  Rasshirenie procedury pre-
ryvaniya sravnivaet novoe znachenie schetchika vremeni sutok so  zna-
cheniem, pokazyvayushchim vremya zaversheniya generacii tona, i kogda eto
znachenie  dostignuto, preryvaet zvuk, nachinaet generaciyu  drugogo
tona i ustanavlivaet vremya ego okonchaniya.

   Vysokij uroven'.

   Generaciya  stroki  zvukov  odnovremenno  s  drugimi operaciyami
yavlyaetsya  odnoj  iz  vozmozhnostej ochen' moshchnogo  operatora  PLAY,
kotoryj detal'no obsuzhdalsya  v  [2.2.5].  Nado  prosto dobavit' v
nachalo upravlyayushchej stroki MB.  |to sokrashchenie ot Music Background
(fonovaya muzyka); dlya togo  chtoby  zastavit'  PLAY prekratit' vse
drugie operacii, poka generaciya zvukovoj stroki ne budet zavershe-
na, vstav'te MF.  V  nizheprivedennom primere vo vremya risovaniya i
zapolneniya  ramki  ispolnyaetsya  gamma (dlya ego  raboty  trebuetsya
nalichie graficheskih vozmozhnostej).

100 PLAY "MB T100 O3 L4;CDEFG>ABC"  'ispolnyaem nabor not
110 LINE (10,10)-(80,80),1,BF       'odnovremenno risuem ramku

   Nizkij uroven'.

   Privedennaya procedura yavlyaetsya razvitiem procedury, pokazannoj
v predydushchem razdele, na sluchaj  real'nogo  vremeni.  Ona trebuet
ponimaniya, kak pereprogrammirovat' preryvanie tajmera, chto obsuzh-
dalos' v [2.1.7]. Na etu proceduru dolzhen ukazyvat' vektor prery-
vaniya  i  togda ona budet vypolnyat'sya 18.2 raza v  sekundu, v  te
momenty, kogda budet obnovlyat'sya  znachenie schetchika vremeni sutok
BIOS. Obychno, budut vypolnyat'sya tol'ko neskol'ko strochek, kotoryh
dostatochno, chtoby  opredelit',  chto  vremya izmeneniya zvuka eshche ne
nastupilo,  - i procedura osvozhdaet processor dlya resheniya  drugih
zadach.
   Schetchik vremeni sutok BIOS ispol'zuetsya dlya izmereniya dlitel'-
nosti kazhdoj noty.  Pri perehode ot odnoj noty k drugoj, dlitel'-
nost' novoj noty vychislyaetsya  kak  chislo impul'sov schetchika i eto
znachenie  dobavlyaetsya  k tekushchemu ego znacheniyu.  Kazhdyj  raz  pri
vyzove procedury proveryaetsya  tekushchee  znachenie  schetchika vremeni
sutok, i kogda ozhidaemoe vremya nakonec nastupaet, to  vypolnyaetsya
nabor operacij po poisku novoj  noty, programmirovaniyu ee chastoty
v  kanale  2 mikroshemy 8253 i ustanovleniyu novogo schetchika  dli-
tel'nosti.  Dobavochnyj  kod  trebuetsya  dlya obrabotki special'nyh
sluchaev pervoj i poslednej not v stroke.


;---v segmente dannyh
BEAT        DB   10,9,8,7,6,5,4,3,2   ;dlitel'nost' not
FREQUENCY   DW   2280,2031,1809,1709  ;tablica chastot
            DW   1521,1355,1207,1139  ;
MELODY      DB   1,2,3,4,5,6,7,8,0FFH ;nomer chastoty v tablice
HOLDIP      DW   0                    ;zapominaem original'nyj
HOLDCS      DW   0                    ;vektor preryvaniya
SOUND_NOW?  DB   1                    ;zvuk vklyuchen?
FIRST_NOTE? DB   1                    ;pervaya nota?
END_NOTE    DW   0                    ;schetchik konca noty
WHICH_NOTE  DW   0                    ;ukazatel' na tekushchuyu notu
;---inicializaciya vektora preryvaniya
   ;izmenenie vektora
   PUSH  DS                      ;sohranyaem registr
   MOV   AX,SEG MELODY2          ;segment procedury
   MOV   DS,AX                   ;pomeshchaem v DS
   MOV   DX,OFFSET MELODY2       ;smeshchenie procedury
   MOV   AL,1CH                  ;nomer vektora preryvaniya
   MOV   AH,25H                  ;funkciya ustanovki vektora
   INT   21H                     ;izmenenie vektora
   POP   DS                      ;vosstanovlenie registra
;
;---programma rabotaet dal'she, postoyanno vyzyvaya proceduru
;
;---v konce programmy vosstanavlivaem vektor preryvaniya
   MOV   DX,0FF53H        ;vosstanavlivaem original'nye
   MOV   AX,0F000H        ;znacheniya dlya vektora 1CH
   MOV   DS,AX            ;
   MOV   AL,1CH           ;nomer preryvaniya
   MOV   AH,25H           ;funkciya ustanovki vektora
   INT   21H              ;vosstanavlivaem vektor
   RET                    ;

;---eto samo preryvanie
MELODY2    PROC FAR
           PUSH AX        ;sohranyaem izmenyaemye registry
           PUSH BX        ;
           PUSH CX        ;
           PUSH DX        ;
           PUSH DI        ;
           PUSH SI        ;
           PUSH DS        ;
           MOV  AX,SS:[114]   ;berem nachal'nyj DS so steka
           MOV  DS,AX         ;vosstanavlivaem ego
           CMP  SOUND_NOW?,1  ;nuzhen li zvuk?
           JE   PLAY_IT       ;esli net, to vyhod iz preryvaniya
           JMP  NOT_NOW       ;
PLAY_IT:   CMP  FIRST_NOTE?,0 ;eto pervaya nota?
           JE   TIME_CHECK    ;esli net, to na ustanovku vremeni


;---inicializaciya
PORT_B        EQU  61H           ;opredelyaem imena portov
COMMAND_REG   EQU  43H           ;
LATCH2        EQU  42H           ;
              IN   AL,PORT_B     ;berem status porta B
              OR   AL,00000011B  ;razreshaem dinamik i tajmer
              OUT  PORT_B,AL     ;posylaem bajt obratno
              MOV  SI,0          ;ukazatel' na stroki
              MOV  AL,0B6H       ;inicializaciya kanala 2 tajmera
              OUT  COMMAND_REG,AL   ;posylaem v komandnyj registr
              MOV  FIRST_NOTE?,0    ;sbrasyvaem flag pervoj noty
;---ishchem notu, poluchaem ee chastotu, posylaem v kanal 2
NEXT_NOTE:    LEA  BX,MELODY     ;berem smeshchenie stroki melodii
              MOV  SI,WHICH_NOTE ;ukazatel' na tekushchuyu notu
              MOV  AL,[BX][SI]   ;kod tekushchej noty stroki
              CMP  AL,0FFH       ;proveryaem priznak konca
              JE   NO_MORE       ;esli da, to na konec
              CBW                ;inache v slovnyj format
   ;poluchaem chastotu
              MOV  BX,OFFSET FREQUENCY  ;smeshchenie tablicy chastot
              DEC  AX            ;nachinaem otschet s nulya
              SHL  AX,1          ;umnozhaem na 2, t.k. slovnaya
              MOV  DI,AX         ;adresuemsya cherez DI
              MOV  DX,[BX][DI]   ;poluchaem chastotu iz tablicy
   ;nachinaem ispolnenie noty
              MOV  AL,DL         ;gotovim mladshij bajt chastoty
              OUT  LATCH2,AL     ;posylaem v registr zadvizhki
              MOV  AL,DH         ;gotovim starshij bajt
              OUT  LATCH2,AL     ;posylaem ego
;---pustoj cikl, opredelyayushchij dlitel'nost' not
TIME_IT:      MOV  AH,0          ;fnukciya chteniya schetchika
              INT  1AH           ;poluchaem znachenie schetchika
              MOV  BX,OFFSET BEAT  ;smeshchenie stroki dlin not
              MOV  CL,[BX][SI]   ;dlitel'nost' tekushchej noty
              MOV  CH,0          ;
              MOV  BX,DX         ;mladshee slovo znacheniya schetchika
              ADD  BX,CX         ;dobavlyaem dlinu v impul'sah
              MOV  END_NOTE,BX   ;zapominaem vremya okonchaniya
TIME_CHECK:   MOV  AH,0          ;funkciya chteniya schetchika
              INT  1AH           ;chitaem schetchik
              CMP  DX,END_NOTE   ;sravnivaem s nuzhnym
              JNE  NOT_NOW       ;esli neravno, to vyhodim
              MOV  SI,WHICH_NOTE ;inache, berem sleduyushchuyu notu
              INC  SI            ;uvelichivaem nomer noty
              MOV  WHICH_NOTE,SI ;zapominaem ego
              JMP  NEXT_NOTE     ;nachinaem sleduyushchuyu notu
;---zavershenie procedury
NO_MORE:      IN   AL,PORT_B     ;berem status porta B
              AND  AL,0FCH       ;vyklyuchaem dinamik
              OUT  61H,AL        ;vozvrashchaem bajt
              MOV  SOUND_NOW?,0  ;vosstanavlivaem peremennye
              MOV  FIRST_NOTE?,1 ;


NOT_NOW:      POP  DS            ;vosstanavlivaem registry
              POP  SI            ;
              POP  DI            ;
              POP  DX            ;
              POP  CX            ;
              POP  BX            ;
              POP  AX            ;
              IRET               ;vozvrat iz preryvaniya
MELODY2       ENDP





   Plavnye perehody tonov proizvodyatsya za schet nepreryvnogo izme-
neniya chastoty. |togo mozhno  dostignut' kak v Bejsike, tak i prog-
rammiruya  na nizkom urovne.  |tot zvukovoj effekt  mozhno  sdelat'
bolee vyrazitel'nym, esli  nemnogo umen'shat' dlitel'nost' kazhdogo
segmenta tona pri povyshenii zvuka ili slegka uvelichivat' dlitel'-
nost' pri ponizhenii.

   Vysokij uroven'.

   V Bejsike nado prosto pomestit' operator SOUND [2.2.2] v cikl,
ispol'zuya ochen' malye dliny tonov. Pri kazhdom novom prohode cikla
nado uvelichivat' chastotu.  Smotrite  [2.2.8], gde priveden primer
ispol'zovaniya operatora PLAY dlya bolee bystryh perehodov.

100 FOR N = 1 TO 500 STEP 15
110 SOUND 400 + N,1
120 NEXT

   Nizkij uroven'.

   Proshche  vsego ispol'zovat' metod generacii  zvuka,  upravlyaemyj
mikroshemoj interfejsa s periferiej 8255. Prosto menyajte znachenie
bita  1 porta B mezhdu 0 i 1, ispol'zuya dlya otscheta vremeni pustoj
cikl, kak pokazano v [2.2.2].   Pri nachale kazhdogo novogo pustogo
cikla,  zaschet zasylki znacheniya v CX, slegka izmenyajte eto znache-
nie. Zdes' ton povyshaetsya:

;---zapret mikroshemy tajmera
PB       EQU  61H        ;adres porta B mikroshemy 8255
         IN   AL,PB      ;poluchaem iz nego bajt
         OR   AL,1       ;sbrasyvaem bit 0
         OUT  PB,AL      ;vozvrashchaem bajt v port
;---ustanovka chastoty i dlitel'nosti zvuka
         MOV  BX,9000    ;nachal'noe znachenie schetchika
         MOV  DX,3000    ;dlitel'nost' zvuka 3000 ciklov
REPEAT:                  ;syuda vozvrashchaemsya posle cikla
;---ustanovka bita dinamika
         OR   AL,00000010B   ;ustanavlivaem bit 1
         OUT  PB,AL          ;posylaem bajt v port B
         MOV  CX,BX          ;ustanovka schetchika dlya 1/2 cikla
CYCLE1:  LOOP CYCLE1         ;pustoj cikl na 1000 povtorov
;---sbros bita dinamika
         AND  AL,11111101B   ;sbrasyvaem bit 1
         OUT  PB,AL          ;posylaem bajt v port
         MOV  CX,BX          ;ustanovka schetchika
CYCLE2:  LOOP CYCLE2         ;pustoj cikl
;---perehod k sleduyushchemu ciklu
         DEC  BX             ;uvelichivaem chastotu, umen'shaya
         DEC  BX             ;schetchik
         DEC  DX             ;umen'shaem ostavshuyusya dlitel'nost'
         JNZ  REPEAT         ;esli DX ne 0, to novyj cikl


|tot  prostoj  metod privodit k tomu, chto vysokie  tona  prohodyat
znachitel'no bystree, chem  nizkie.   Dlya korotkih intervalov takoj
effekt mozhet byt' zhelatel'nym, a kogda on ne nuzhen, nado dobavit'
kod, kotoryj pri povyshenii tona  peresylaet v DX bol'shie znacheniya
na sleduyushchem cikle.





   Zvukovye  effekty  obychno dostigayutsya  nepreryvnym  izmeneniem
chastoty tona. Tol'ko PCjr  dostatochno  horosho oborudovan dlya etoj
celi (sm. obsuzhdenie v [2.2.1]).  Na drugih mashinah nel'zya proiz-
vodit' zvukovye effekty odnovremenno s drugimi operaciyami.

   Vysokij uroven'.

   Blagodarya moshchnosti svoih operatorov SOUND i PLAY Bejsik pozvo-
lyaet dostatochno legko sozdavat' slozhnye zvukovye effekty.  No vse
dolzhno byt' skonstruirovano iz  chistyh  muzykal'nyh  tonov, a eto
znachit,  chto  effekt distorcii zvuka dolzhen dostigat'sya  za  schet
takogo bystrogo  izmeneniya  tona,  chto  uho ne uspevaet razdelit'
tona.  Naprimer, dusherazdirayushchee "chirikan'e" mozhet byt'  polucheno
pri bystrom pereklyuchenii mezhdu odnim i tem zhe tonom, otstoyashchim na
neskol'ko oktav:

100 FOR N = 1 TO 100     'ustanovka dlitel'nosti
110 PLAY "L64 T255"      'samyj bystryj temp
120 PLAY "O1A"           'vydaem nizkoe A
130 PLAY "O5A"           'vydaem vysokoe A
140 NEXT                 'povtor

Pri izmenenii chastoty vsego na neskol'ko gerc poluchaem vibraciyu:

100 FOR N = 1 TO 100     'ustanovka dlitel'nosti
110 SOUND 440,1          'vydaem notu A
120 SOUND 445,1          'nemnogo menyaem chastotu
130 NEXT                 'povtor

Drugaya  tehnika  zaklyuchaetsya vo vlozhenii plavno menyayushchihsya  tonov
vnutr' posledovatel'nosti, kotoraya  sama gulyaet po chastotam vverh
ili vniz.  Na ris.  2-6 pokazana dvizhushchayasya vverh  posledovatel'-
nost'. Mnogie igry s labirintami ispol'zuyut etu tehniku:

100 FOR I = 1 TO 10   'chislo povtorenij
110 FOR J = 1 TO 6    'chislo raznyh oktav
120 PLAY "MBL64T255O=J;BA#AG#GF#FED#DC#CC#DD#EFF#GG#AA#B"
130 NEXT              'povtor v bolee vysokoj oktave
140 NEXT              'povtor vsej posledovatel'nosti

   PCjr znachitel'no bolee moshchnyj, chem ostal'nye mashiny, blagodarya
special'noj  mikrosheme generatora zvuka.  Operator  NOISE  mozhet
proizvodit' mnozhestvo zvukov, format etogo operatora takoj:

   NOISE istochnik, gromkost', dlitel'nost'

Istochnik  -  eto chislo ot 0 do 7, znachenie kotorogo  privedeno  v
tablice:


   0       periodicheskij shum v vysokom diapazone
   1       periodicheskij shum v srednem diapazone
   2       periodicheskij shum v nizkom diapazone
   3       periodicheskij shum, diapazon menyaetsya s kanalom 3
   4       belyj shum v vysokom diapazone
   5       belyj shum v srednem diapazone
   6       belyj shum v nizkom diapazone
   7       belyj shum, diapazon menyaetsya s kanalom 3
Gromkost' zadaetsya chislom ot  0  do  15,  gde 0 sootvetstvuet ot-
sutstviyu zvuka. Dlitel'nost' ukazyvaetsya chislom impul'sov schetchi-
ka vremeni sutok, kotorye otschityvayutsya 18.2 raza v sekundu.

   Nizkij uroven'.

   Lyuboj iz sposobov, pokazannyh na Bejsike mozhet byt' realizovan
na  assemblere, hotya, kak vidno iz predydushchih razdelov, eto  tre-
buet zatrat na programmirovanie.  Krome togo, assembler pozvolyaet
generirovat'  nechistye  tona, kogda interval, v techenie  kotorogo
dinamik vklyuchen, ne raven intervalu, v techenie kotorogo on vyklyu-
chen.  Takoe narushenie simmetrii mozhet privodit' k zhuzhzhashchim i brya-
kayushchim zvukam. Kogda otnoshenie etih intervalov sostavlyaet, skazhem
50  k 1, to poluchaem zhuzhzhanie.  Esli uvelichit' otnoshenie eshche v 10
- 20 raz, to zhuzhzhanie perehodit  v  otdel'nye  bryakayushchie zvuki. V
lyubom  sluchae zvuk generiruetsya mikroshemoj interfejsa s  perife-
riej 8255, s pomoshch'yu  tehniki  pokazannoj  v  [2.2.2]. Vot primer
zhuzhzhaniya:

NUMBER_CYCLES  EQU  300     ;chislo pereklyuchenij dinamika
FREQUENCY1     EQU  50      ;vremya, kogda dinamik vklyuchen
FREQUENCY2     EQU  3200    ;vremya, kogda dinamik vyklyuchen
PORT_B         EQU  61H     ;adres porta B mikroshemy 8255
            CLI                  ;zapret preryvanij
            MOV  DX,NUMBER_CYCLES;DX schitaet dlinu tona
            IN   AL,PORT_B       ;poluchaem status porta
            AND  AL,11111110B    ;otklyuchaem dinamik ot tajmera
NEXT_CYCLE: OR   AL,00000010B    ;vklyuchaem dinamik
            OUT  PORT_B,AL       ;posylaem komandu
            MOV  CX,FREQUENCY1   ;zaderzhka dlya pervoj chasti
FIRST_HALF: LOOP FIRST_HALF      ;
            AND  AL,11111101B    ;vyklyuchaem dinamik
            OUT  PORT_B,AL       ;posylaem komandu
            MOV  CX,FREQUENCY2   ;zaderzhka dlya vtoroj chasti
SECND_HALF: LOOP SECND_HALF      ;
            DEC  DX              ;umen'shaem chislo ciklov
            JNZ  NEXT_CYCLE      ;esli 0, to pora konchat'
            STI                  ;razreshaem preryvaniya

Dlya  sozdaniya bryakayushchih zvukov mozhno ispol'zovat' etot zhe kod, no
nado zamenit' znachenie FREQUENCY2 na velichinu okolo 40000.





   Tol'ko mikroshema generatora  zvuka,  imeyushchayasya v PCjr, pozvo-
lyaet  odnovremenno generirovat' raznye zvuki (sm.   obsuzhdenie  v
[2.2.1]). Odnako assembler pozvolyaet ob®edinit' dva sposoba gene-
racii  zvuka,  chto sozdaet imitaciyu odnovremennoj generacii  dvuh
raznyh zvukov.  Interferenciya etih dvuh signalov privodit k slozh-
noj  forme zvukovoj volny.  Kazhdyj iz dvuh zvukov  imeet  men'shuyu
gromkost', poetomu v rezul'tate  poluchaetsya  skoree zhuzhzhanie, chem
dva raznyh golosa. |tot priem real'no polezen tol'ko dlya sozdaniya
zvukovyh effektov.

   Nizkij uroven'.

   Nado prosto ob®edinit' dva metoda  generacii zvuka, pokazannye
v [2.2.2] i [2.2.3]. Nachnite zvuk cherez kanal 2 mikroshemy tajme-
ra.  Zatem modulirujte  vyhod  dinamika,  za  schet bita 1 porta B
mikroshemy  interfejsa s periferiej.  Vtoroe dejstvie  opredelyaet
prodolzhitel'nost' zvuka. Ne zabud'te vyklyuchit' mikroshemu tajmera
pri zavershenii.

;---nachinaem generaciyu zvuka cherez kanal 2 tajmera
      IN   AL,61H          ;poluchaem bajt iz porta B
      OR   AL,3            ;ustanavlivaem mladshie dva bajta
      OUT  61H,AL          ;posylaem bajt obratno
      MOV  AL,10110110B    ;cepochka dlya komandnogo registra 8253
      OUT  43H,AL          ;posylaem v registr
      MOV  AX,600H         ;schetchik dlya kanala 2
      OUT  42H,AL          ;posylaem mladshij bajt
      MOV  AL,AH           ;gotovim starshij bajt
      OUT  42H,AL          ;posylaem starshij bajt
;---generiruem vtoruyu chastotu mikroshemoj 8255
NUMBER_CYCLES  EQU  9000           ;chislo pereklyuchenij
FREQUENCY      EQU  150            ;zaderzhka dlya poloviny cikla
               CLI                 ;zapret preryvanij
               MOV  DX,NUMBER_CYCLES  ;DX schitaet dlinu tona
               IN   AL,61H         ;poluchaem status porta
               AND  AL,11111111B   ;otklyuchaem dinamik ot tajmera
NEXT_CYCLE:    OR   AL,00000010B   ;vklyuchaem dinamik
               OUT  61H,AL         ;posylaem nazad v port
               MOV  CX,FREQUENCY   ;zaderzhka na 1/2 cikla
FIRST_HALF:    LOOP FIRST_HALF     ;
               AND  AL,11111101B   ;vyklyuchaem dinamik
               OUT  61H,AL         ;posylaem komandu v port
               MOV  CX,FREQUENCY   ;zaderzhka na 1/2 cikla
SECOND_HALF:   LOOP SECOND_HALF    ;
               DEC  DX             ;menyaem schetchik ciklov
               JNZ  NEXT_CYCLE     ;esli 0, to pora konchat'
               STI                 ;razreshaem preryvaniya
;---vyklyuchenie kanala 2 mikroshemy tajmera
               IN   AL,61H         ;poluchaem status porta
               AND  AL,11111100B   ;sbrasyvaem 2 mladshih bita
               OUT  61H,AL         ;posylaem bajt obratno







   Klaviatura  soderzhit intelevskij mikroprocessor, kotoryj vosp-
rinimaet kazhdoe nazhatie  na  klavishu  i  vydaet skan-kod v port A
mikroshemy  interfejsa  s  periferiej [1.1.1],  raspolozhennoj  na
sistemnoj plate.  Skan-kod eto odnobajtnoe chislo, mladshie 7 bitov
kotorogo predstavlyayut identifikacionnyj nomer, prisvoennyj kazhdoj
klavishe. Tablica skan-kodov privedena v [3.3.2]. Na vseh mashinah,
krome  AT, starshij bit koda govorit o tom, byla li klavisha nazhata
(bit = 1, kod nazhatiya) ili  osvobozhdena  (bit = 0, kod osvobozhde-
niya).   Naprimer, 7-bitnyj skan-kod klavishi B - 48, ili 110000  v
dvoichnoj sisteme. Kogda eta klavisha nazhimaetsya, to v port A posy-
laetsya  kod 10110000, a kogda ee otpustili - kod 00110000.  Takim
obrazom, kazhdoe nazhatie na  klavishu  dvazhdy registriruetsya v mik-
rosheme 8255.  I kazhdyj raz mikroshema 8255 vydaet  podtverzhdenie
mikroprocessoru klaviatury. AT rabotaet nemnogo po-drugomu, posy-
laya  v  oboih  sluchayah odin i tot zhe skan-kod, no  predvaryaya  ego
kodom F0H, kogda klavisha otpuskaetsya.
   Kogda skan-kod vydaetsya  v  port  A,  to vyzyvaetsya preryvanie
klaviatury (INT 9).  Processor momental'no prekrashchaet svoyu rabotu
i vypolnyaet proceduru,  analiziruyushchuyu  skan-kod.  Kogda postupaet
kod  ot  klavishi sdviga ili pereklyuchatelya, to  izmenenie  statusa
zapisyvaetsya v pamyat'.  Vo vseh ostal'nyh sluchayah skan-kod trans-
formiruetsya v kod simvola, pri uslovii, chto on podaetsya pri nazha-
tii klavishi (v protivnom sluchae, skan-kod otbrasyvaetsya).  Konech-
no, procedura snachala opredelyaet ustanovku klavish sdviga i perek-
lyuchatelej, chtoby  pravil'no  poluchit'  vvodimyj  kod (eto "a" ili
"A"?).  Posle etogo vvedennyj kod pomeshchaetsya v bufer  klaviatury,
kotoryj yavlyaetsya oblast'yu  pamyati, sposobnoj zapomnit' do 15 vvo-
dimyh  simvolov, poka programma slishkom zanyata, chtoby  obrabotat'
ih. Na ris. 3-1 pokazan put', kotoryj prohodit nazhatie na klavishu
pered tem, kak pokast' v Vashu programmu.
   Imeetsya  dva  tipa  kodov simvolov, kody  ASCII i  rasshirennye
kody.  Kody ASCII - eto bajtnye chisla, kotorye sootvetstvuyut ras-
shirennomu  naboru  kodov  ASCII dlya IBM PC,  kotoryj  priveden  v
[3.3.3]. Dlya IBM PC etot nabor  vklyuchaet  obychnye simvoly pishushchej
mashinki,  a takzhe ryad special'nyh bukv i simvolov  psevdografiki.
ASCII kody vklyuchayut takzhe  32  upravlyayushchih  koda,  kotorye obychno
ispol'zuyutsya  dlya peredachi komand periferijnym ustrojstvam, a  ne
vyvodyatsya kak simvoly na ekrane; odnako kazhdyj iz nih imeet soot-
vetstvuyushchij  simvol,  kotoryj  mozhet byt' vyveden na  displej,  s
ispol'zovaniem pryamoj adresacii displejnoj pamyati [4.3.1]. (Stro-
go govorya, tol'ko pervye 128 simvolov yavlyayutsya nastoyashchimi  simvo-
lami ASCII, tak kak  ASCII  -  eto  abbreviatura  ot Amerikanskij
standartnyj  kod dlya obmena informaciej.  No programmisty  obychno
govoryat o kodah ASCII, chtoby otlichit'  ih ot drugih chisel. Napri-
mer,  "ASCII 8" otnositsya k klavishe "Backspace", v to  vremya  kak
"8" - eto cifra, kotoroj sootvetstvuet ASCII 56).
   Vtoroj nabor  kodov,  rasshirennye  kody, prisvoen klavisham ili
kombinaciyam  klavish, kotorye ne imeyut predstavlyayushchego ih  simvola
ASCII, takim kak funkcional'nye klavishi ili kombinacii s klavishej
Alt.   Rasshirennye kody imeyut dlinu 2 bajta, prichem  pervyj  bajt
vsegda ASCII 0. Vtoroj bajt  -  nomer  rasshirennogo  koda, spisok
kotoryh  priveden  v  [3.3.5].  Naprimer, kod  0:30  predstavlyaet
Alt-A.  Nachal'nyj nol' pozvolyaet  programme prinadlezhit li dannyj
kod naboru ASCII ili rasshirennomu naboru.


   Imeetsya  neskol'ko  kombinacij klavish, kotorye vypolnyayut  spe-
cial'nye funkcii i ne generiruyut skan-kody.  |ti kombinacii vklyu-
chayut <Ctrl-Break>, <Ctrl-Alt-Del> i <PrtSc>, plyus <SysReq> dlya AT
i <Ctrl-Alt-strelka vlevo, -strelka  vpravo, -CapsLock, -Ins> dlya
PCjr.  |ti isklyucheniya privodyat k zaranee predopredelennym rezul'-
tatam [3.3.2]. Vse ostal'nye  nazhatiya klavish dolzhny interpretiro-
vat'sya  Vashej programmoj i esli oni imeyut special'noe naznachenie,
skazhem sdvinut' kursor vlevo, to Vasha  programma dolzhna soderzhat'
kod, obespechivayushchij dostizhenie etogo effekta.
   K schast'yu operacionnaya sistema predostavlyaet razlichnye  proce-
dury dlya chteniya kodov iz bufera  klaviatury, vklyuchaya sredstva dlya
polucheniya srazu celoj stroki.  Poskol'ku eti procedury  pozvolyayut
delat' prakticheski vse, chto  Vy  mozhete  pozhelat', to prakticheski
bessmyslenno pisat' svoi procedury obrabotki vvoda s klaviatury i
poetomu v dannoj glave imeetsya ochen' malo primerov programmirova-
niya na nizkom urovne. Odnako soderzhitsya obsuzhdenie voprosa o tom,
kak pereprogrammirovat' preryvanie klaviatury.





   Programma dolzhna  ochistit'  bufer  klaviatury,  pered tem, kak
vydat'  zapros  na vvod, isklyuchaya tem samym  postoronnie  nazhatiya
klavish, kotorye mogut k tomu  vremeni  nakopit'sya v bufere. Bufer
mozhet  nakaplivat' do 15 nazhatij na klavishu, nezavisimo ot  togo,
yavlyayutsya li oni odnobajtnymi kodami ASCII ili dvuhbajtnymi rasshi-
rennymi  kodami.  Takim obrazom, bufer dolzhen otvesti  dva  bajta
pamyati dlya kazhdogo nazhatiya  na  klavishu.   Dlya  odnobajtnyh kodov
pervyj bajt soderzhit kod ASCII, a vtoroj - skan-kod klavishi.  Dlya
rasshirennyh kodov pervyj bajt  soderzhit  ASCII  0, a vtoroj nomer
rasshirennogo koda. |tot kod obychno sovpadaet so skan-kodom klavi-
shi, no ne vsegda, poskol'ku  nekotorye  klavishi  mogut kombiniro-
vat'sya s klavishami sdviga dlya generacii razlichnyh kodov.
   Bufer ustroen kak ciklicheskaya ochered', kotoruyu nazyvayut  takzhe
buferom FIFO (pervyj voshel - pervyj  ushel).  Kak i lyuboj bufer on
zanimaet  nepreryvnuyu oblast' adresov pamyati.  Odnako ne  imeetsya
opredelennoj  yachejki  pamyati,  kotoraya  hranit  "nachalo stroki" v
bufere. Vmesto etogo dva ukazatelya hranyat pozicii golovy i hvosta
stroki  simvolov, nahodyashchejsya v bufere v tekushchij  moment.   Novye
nazhatiya klavish zapasayutsya  v  poziciyah,  sleduyushchih  za hvostom (v
bolee starshih adresah pamyati) i sootvetstvenno obnovlyaetsya ukaza-
tel' hvosta bufera.  Posle togo,  kak  izrashodovano vse bufernoe
prostranstvo,  novye  simvoly prodolzhayut vstavlyat'sya,  nachinaya  s
samogo nachala bufernoj oblasti; poetomu  vozmozhny situacii, kogda
golova stroki v bufere imeet bol'shij adres, chem hvost. Posle togo
kak bufer zapolnen, novye vvodimye simvoly ignoriruyutsya, pri etom
preryvanie  klaviatury vydaet gudok cherez dinamik.  Na ris.   3-2
pokazany nekotorye vozmozhnye konfiguracii dannyh v bufere.
   V to vremya kak ukazatel' na  golovu  ustanovlen na pervyj vve-
dennyj  simvol, ukazatel' na hvost ustanovlen na poziciyu za  pos-
lednim vvedennym  simvolom.  Kogda  oba ukazatelya ravny, to bufer
pust.   CHtoby  razreshit' vvod 15 simvolov trebuetsya  16-ya  pustaya
poziciya, 2 bajta  kotoroj  vsegda  soderzhat  kod vozvrata karetki
(ASCII  13)  i skan-kod klavishi <Enter>, ravnyj 28.   |ta  pustaya
poziciya neposredstvenno  predshestvuet  golove stroki simvolov. 32
bajta bufera nachinayutsya s adresa 0040:001E. Ukazateli na golovu i
hvost raspolozheny po adresam 0040:001A i 0040:001C, sootvetstven-
no.   Hotya  pod ukazateli otvedeno 2 bajta,  ispol'zuetsya  tol'ko
mladshij bajt. Znacheniya ukazatelej menyayutsya ot 30 do 60, chto soot-
vetstvuet poziciyam v oblasti dannyh BIOS. Dlya ochistki bufera nado
prosto ustanovit' znachenie yachejki 0040:001A ravnym znacheniyu yachej-
ki 0040:001C.
   Otmetim,  chto programma imeet vozmozhnost' vstavlyat' simvoly  v
bufer, zavershaya stroku simvolom vozvrata karetki i sootvetstvenno
menyaya znacheniya ukazatelej.  Esli eto prodelat' pravil'nym obrazom
pered  zaversheniem programmy, to pri vozvrate upravleniya v MS DOS
eti simvoly budut schitany i  mozhet  byt'  avtomaticheski zagruzhena
drugaya programma.

   Nizkij uroven'.

   V Bejsike dlya polucheniya i izmeneniya znachenij ukazatelej bufera
ispol'zuyutsya operatory PEEK i POKE:


100 DEF SEG = &H40        'ustanavlivaem znachenie segmenta
110 POKE &H1C, PEEK(&H1A) 'vyravnivaem ukazateli

|tot metod ne samyj luchshij.   Nekotorye programmy mogut sozdavat'
bufer  gde-nibud'  v  drugom meste pamyati, a krome  togo,  vsegda
sushchestvuet vozmozhnost', chto posredi  stroki 110 proizojdet prery-
vanie klaviatury, kotoroe izmenit ukazatel' hvosta.  Po etim pri-
chinam luchshe ostavit'  ukazateli  bufera  v  pokoe.  Vmesto etogo,
luchshe chitat' iz bufera do teh por, poka ne budet vozvrashchen simvol
ASCII 0, pokazyvayushchij, chto bufer pust:

100 IF INKEY$<>"" THEN 100   'berem sleduyushchee esli ne nul'

   Srednij uroven'.

   Funkciya  0C preryvaniya 21H vypolnyaet lyubuyu iz funkcij vvoda  s
klaviatury 1, 6, 7, 8 i A (opisannyh v etoj glave), no pered etim
chistit  bufer  klaviatury.  Nado prosto pomestit'  nomer  funkcii
vvoda v AL (v etom primere - 1):

;---ochistka bufera pered ozhidaniem nazhatiya klavishi
   MOV  AH,0CH    ;vybiraem funkciyu DOS 0CH
   MOV  AL,1      ;vybiraem funkciyu vvoda simvola
   INT  21H       ;chistim bufer, zhdem vvoda

   Nizkij uroven'.

   Kak i v primere vysokogo  urovnya  delaem znachenie ukazatelya na
hvost ravnym znacheniyu ukazatelya na golovu.  Dlya izbezhaniya vliyaniya
preryvaniya klaviatury zapreshchaem  preryvaniya  na vremya modifikacii
ukazatelya:

;---vyravnivaem znacheniya ukazatelej na golovu i hvost
   CLI                   ;zapreshchaem preryvaniya
   SUB  AX,AX            ;obnulyaem registr
   MOV  ES,AX            ;dobavochnyj segment - s nachala pamyati
   MOV  AL,ES:[41AH]     ;berem ukazatel' na golovu bufera
   MOV  ES:[41CH],AL     ;posylaem ego v ukazatel' hvosta
   STI                   ;razreshaem preryvaniya





   Vy mozhete proverit' byl li vvod s klaviatury, ne udalyaya simvol
iz bufera klaviatury.  Bufer  ispol'zuet  dva  ukazatelya, kotorye
otmechayut golovu i hvost ocheredi simvolov, nahodyashchihsya v bufere  v
tekushchij moment. Kogda  znacheniya  etih  ukazatelej ravny, to bufer
pust.   Nado prosto sravnit' soderzhimoe yacheek pamyati 0040:001A  i
0040:001C.  (Nel'zya prosto proverit' simvol, nahodyashchijsya v golove
ocheredi, poskol'ku bufer organizovan v vide ciklicheskoj ocheredi i
poziciya ee golovy postoyanno menyaetsya [3.1.1].)

   Vysokij uroven'.

   Nado prosto ispol'zovat' operator PEEK dlya polucheniya znachenij,
a zatem sravnit' ih:

100 DEF SEG = &H40    'ustanavlivaem segment na nachalo pamyati
110 IF PEEK(&H1A)<>PEEK(&H1C) THEN ... '...to bufer ne pust

   Srednij uroven'.

   Funkciya 0BH preryvaniya 21H vozvrashchaet znachenie 0FFH v registre
AL, kogda bufer  klaviatury  soderzhit  odin  ili bolee simvolov i
znachenie 0, kogda bufer pust:

;---proverka nalichiya simvola v bufere
   MOV  AH,0BH           ;nomer funkcii
   INT  21H              ;vyzyvaem preryvanie 21H
   CMP  AL,0FFH          ;sravnivaem s 0FFH
   JE   GET_KEYSTROKE    ;perehod esli bufer ne pust

   Funkciya 1 preryvaniya BIOS 16H predostavlyaet tu zhe vozmozhnost',
no, krome togo, pokazyvaet kakoj simvol  v bufere. Flag nulya (ZF)
sbrasyvaetsya,  esli bufer pust, i ustanavlivaetsya, esli v  bufere
imeetsya simvol.  V poslednem sluchae kopiya simvola, nahodyashchegosya v
golove bufera, pomeshchaetsya v AX, no simvol iz bufera ne udalyaetsya.
V AL vozvrashchaetsya kod  simvola  dlya  odnobajtnyh  simvolov ASCII,
inache ASCII 0 dlya rasshirennyh kodov, i togda nomer koda - v AH.

;---proveryaem nalichie simvola v bufere
   MOV  AH,1             ;nomer funkcii
   INT  16H              ;proverka nalichiya simvola
   JZ   NO_CHARACTER     ;perehod esli ZF = 1
;---imeetsya simvol - smotrim kakoj
   CMP  AL,0             ;eto rasshirennyj kod?
   JE   EXTENDED_CODE    ;esli da, to na druguyu vetku

   Nizkij uroven'.

   Kak i v primere vysokogo urovnya prosto sravnivaem ukazateli:

;---sravnivaem ukazateli na golovu i hvost
   MOV  AX,0           ;ustanavlivaem dobavochnyj segment
   MOV  ES,AX          ;na nachalo pamyati
   MOV  AL,ES:[41AH]   ;berem odin ukazatel'
   MOV  AH,ES:[41CH]   ;berem drugoj ukazatel'
   CMP  AH,AL          ;sravnivaem ih
   JNE  GET_KEYSTROKE  ;esli neravny, to k procedure vvoda





   Obychno  vvodimye simvoly vyvodyatsya na ekran, chtoby bylo vidno,
chto napechatano.  No inogda  avtomaticheskoe  eho na ekrane nezhela-
tel'no.  Naprimer, vybor punkta menyu po nazhatiyu klavishi.   Inogda
nado snachala proverit' vvodimye  simvoly  na oshibku pered vyvodom
na ekran.  V chastnosti, lyubaya programma, obrabatyvayushchaya rasshiren-
nye kody, dolzhna izbegat'  avtomaticheskogo  eha, tak kak pri etom
pervyj  bajt  etih  kodov (ASCII 0) budet  vyvodit'sya  na  ekran,
vstavlyaya probely mezhdu simvolami.

   Vysokij uroven'.

   Funkciya Bejsika INKEY$ ne daet eho na terminal. Ona vozvrashchaet
stroku  dlinoj  1 bajt dlya simvolov ASCII i  dlinoj 2  bajta  dlya
rasshirennyh kodov. INKEY$ ne ozhidaet nazhatiya klavishi, do teh por,
poka ona ne pomeshchena v cikl, v kotorom ozhidaetsya nazhatie klavishi.
Cikl rabotaet, obrashchayas' k  INKEY$, a zatem prisvaivaya vozvrashchae-
muyu  im stroku peremennoj, v dannom sluchae C$.  Esli  klavisha  ne
byla nazhata, to INKEY$  vozvrashchaet  nulevuyu  stroku, t.e.  stroku
dlinoj nol' simvolov, kotoraya oboznachaetsya dvumya znakami kavychek,
mezhdu kotorymi nichego net (""). Do teh por poka INKEY$ vozvrashchaet
"" - cikl povtoryaetsya: 100 C$=INKEY$:IF C$="" THEN 100.
   V nizheprivedennom primere predpolagaetsya, chto vvodimye simvoly
vybirayut odnu iz  vozmozhnostej  menyu  i  kazhdyj  vybor privodit k
vypolneniyu  opredelennoj  procedury programmy.  Vybor mozhet  byt'
sdelan za schet nazhatiya klavish  A,  B, C ... (davaya 1-bajtnye kody
ASCII) ili Alt-A, Alt-B, Alt-C ...  (davaya 2-bajtnye  rasshirennye
kody). Dlya ih  raspoznavaniya  ispol'zuetsya  funkciya  LEN, kotoraya
opredelyaet byla li stroka dlinoj v 1 ili 2 bajta.  V sluchae kodov
ASCII nabor operatorov  IF...THEN  srazu nachinaet proveryat' kakaya
klavisha byla nazhata, otsylaya programmu na sootvetstvuyushchuyu  proce-
duru. V sluchae 2-bajtnyh  kodov  upravlenie  peredaetsya otdel'noj
procedure.  V etoj procedure funkciya RIGHT$ ubiraet levyj simvol,
kotoryj prosto raven nulyu  i  tol'ko  otmechaet  rasshirennyj  kod.
Zatem ispol'zuetsya funkciya ASC dlya preobrazovaniya stroki iz  sim-
vol'noj formy v chislovuyu.  I,  nakonec,  vtoraya  seriya operatorov
IF...THEN proveryaet poluchivsheesya chislo na sootvetstvuyushchie  Alt-A,
Alt-B i t.d.

100 C$ = INKEY$:IF C$="" THEN 100   'ozhidaem nazhatiya klavishi
110 IF LEN(C$)=2 THEN 500           'esli rassh. kod - na 500
120 IF C$="a" OR C$="A" THEN GOSUB 1100 'eto A?
130 IF C$="b" OR C$="B" THEN GOSUB 1200 'eto B?
140 IF C$="c" OR C$="C" THEN GOSUB 1300 'eto C?
 .
 .
500 C$=RIGHT$(C$,1)        'poluchaem vtoroj bajt rassh. koda
510 C=ASC(C$)              'preobrazuem ego v chislo
520 IF C=30 THEN GOSUB 2100  'eto Alt-A?
530 IF C=48 THEN GOSUB 2200  'Alt-B?
540 IF C=46 THEN GOSUB 2300  'Alt-C?


Otmetim,  chto v stroke 120 (i posleduyushchih) mozhno takzhe  ispol'zo-
vat' chislovye znacheniya kodov ASCII:

120 IF C=97 OR C=65 THEN GOSUB 1100

Konechno nado snachala  preobrazovat'  C$ v formu celogo chisla, kak
eto sdelano v stroke 510. V programmah, v kotoryh trebuetsya dlin-
naya cepochka takih operatorov,  mozhno  sekonomit' mesto, izmenyaya C
takim  obrazom,  chtoby ona vsegda sootvetstvovala libo  verhnemu,
libo nizhnemu registru.  Snachala  nuzhno  tol'ko proverit', chto kod
ASCII  C$  nahoditsya v pravil'nom diapazone.   Zatem  ustanovit',
men'she li etot kod 91, togda  my  imeem  delo s simvolom verhnego
registra.   Esli eto tak, to nado dlya perevoda v  nizhnij  registr
dobavit' 32.  V protivnom  sluchae,  ostavit' vse kak est'.  Posle
etogo  budet dostatochno bolee korotkogo operatora, takogo kak  IF
C=97 THEN ... Vot kod etoj procedury:

500 C=ASC(C$)         'poluchaem ASCII kod simvola
510 IF NOT ((C>64 AND C<91)OR(C>96 AND C<123)) THEN ...
520 IF C<91 THEN C=C+32  'privodim vse k nizhnemu registru
530 IF C=97 THEN ...     '... nachinaem proverku znachenij

   Srednij uroven'.

   Funkcii 7 i 8 preryvaniya 21H ozhidayut vvoda simvola, esli bufer
klaviatury pust, a kogda on poyavlyaetsya, to ne vyvoditsya na ekran.
Pri etom funkciya 8 opredelyaet Ctrl-Break  (i iniciiruet proceduru
obrabotki Ctrl-Break[3.2.8]), a funkciya 7 ne reagiruet na nego. V
oboih sluchayah simvol  vozvrashchaetsya  v AL. Kogda AL soderzhit ASCII
0, to poluchen rasshirennyj kod.  Povtorite preryvanie i v AL  poya-
vitsya vtoroj bajt rasshirennogo koda.

;---poluchaem vvedennyj simvol
      MOV  AH,7           ;nomer funkcii
      INT  21H            ;ozhidaem vvod simvola
      CMP  AL,0           ;proverka na rasshirennyj kod
      JE   EXTENDED_CODE  ;esli da, to na osobuyu proceduru
       .                  ;inache, kod simvola v AL

;---procedura obrabotki rasshirennyh kodov
EXTENDED_CODE:  INT  21H        ;berem vtoroj bajt koda
                CMP  AL,75      ;proveryaem na "strelku-vlevo"
                JNE  C_R        ;esli net, to sled. proverka
                JMP  CURSOR_LEFT;esli da, to na proceduru
C_R:            CMP  AL,77      ;sravnivaem dal'she i t.d.

   BIOS obespechivaet proceduru,  kotoraya predostavlyaet te zhe voz-
mozhnosti, chto i funkcii MS DOS.  Pomestite 0 v AH i vyzovite pre-
ryvanie 16H. Funkciya ozhidaet vvoda simvola i vozvrashchaet ego v AL.
V etom sluchae i rasshirennye kody obrabatyvayutsya za odno  preryva-
nie. Esli v AL  soderzhitsya  0,  to  v  AH budet soderzhat'sya nomer
rasshirennogo koda. Pri eto ne obrabatyvaetsya Ctrl-Break.


;---zhdem nazhatiya klavishi
   MOV  AH,0       ;nomer funkcii ozhidaniya vvoda
   INT  16H        ;poluchaem vvedennyj kod
   CMP  AL,0       ;proverka na rasshirennyj kod
   JE   EXTENDED_CODE   ;esli da, to na spec. proceduru
    .                   ;inache simvol v AL

;---procedura obrabotki rasshirennogo koda
EXTENDED_CODE:  CMP  AH,75   ;berem rasshirennyj kod iz AH
                             ;i t.d.





   Pri  vvode  dannyh i teksta, eho vvodimyh simvolov obychno  vy-
daetsya na ekran.  Pri etom takie  simvoly kak vozvrat karetki ili
zaboj  perevodyatsya  v sootvetstvuyushchie peremeshcheniya  kursora, a  ne
izobrazhayutsya kak ASCII simvoly dlya etih kodov.  Vydacha eha prois-
hodit  v toj pozicii, gde predvaritel'no byl ustanovlen kursor  i
tekst avtomaticheski perenositsya na  sleduyushchuyu stroku pri dostizhe-
nii  konca tekushchej.  Perenos na sleduyushchuyu stroku ne trebuet  spe-
cial'nogo koda, poskol'ku  simvoly pomeshchayutsya v sleduyushchuyu poziciyu
bufernoj  pamyati displeya, kotoraya predstavlyaet iz sebya odnu dlin-
nuyu stroku, vklyuchayushchuyu vse 25 strok displeya.

   Vysokij uroven'.

   V Bejsike nado perehvatit' vvedennyj simvol s pomoshch'yu operato-
ra INKEY$, kak pokazano  v  [3.1.3].   Zatem  ego nado vyvesti na
ekran, prezhde chem poluchat' takim zhe sposobom sleduyushchij. Dlya vyvo-
da mozhno ispol'zovat' libo  operator  PRINT, libo operatorom POKE
pryamo  pomestit'  simvol v videobufer,  ispol'zuya  otobrazhenie  v
pamyat', kak pokazano v [4.3.1] (bufer nachinaetsya s segmenta pamya-
ti  &HB000  dlya monohromnogo adaptera i s &HB800 -  dlya  cvetnogo
adaptera). Pri ispol'zovanii  PRINT ne zabud'te postavit' v konce
dvoetochie, inache budet avtomaticheski dobavlen kod vozvrata karet-
ki. Nizhe privedeny primery ispol'zovaniya oboih metodov.  Pri etom
ne  provoditsya nikakogo analiza na upravlyayushchie simvoly.  Vvodimye
simvoly formiruyutsya v vide stroki dannyh v peremennoj KEYSTROKE$.

100 ' metod ispol'zuyushchij PRINT
110 LOCATE 10,40           'ustanovka kursora v poziciyu 10,40
120 KEYSTROKE$=""          'ochistka peremennoj
130 C$=INKEY$:IF C$="" THEN 130  'ozhidanie vvoda simvola
140 KEYSTROKE$=KEYSTROKE$ + C$   'zapis' ego v peremennuyu
150 PRINT C$;              'pechat' simvola
160 GOTO 130               'priem sleduyushchego simvola

100 ' metod ispol'zuyushchij POKE
110 DEF SEG = &HB000       'ustanovka segmenta na videobufer
120 POINTER = 1678         'ukazatel' na poziciyu 10,40
130 KEYSTROKE$=""          'ochistka peremennoj
140 C$=INKEY$:IF C$="" THEN 140  'ozhidanie vvoda simvola
150 KEYSTROKE$=KEYSTROKE$ + C$   'zapis' ego v peremennuyu
160 POKE POINTER,ASC(C$)   'pomeshchenie simvola v videobufer
170 POINTER=POINTER + 2    'sdvig ukazatelya na sleduyushchij simvol
180 GOTO 140               'priem sleduyushchego simvola

   Srednij uroven'.

   Funkciya  1  preryvaniya 21H ozhidaet vvoda simvola,  esli  bufer
klaviatury pust, a zatem  vyvodit  ego na ekran v tekushchuyu poziciyu
kursora.   Obrabatyvaetsya  Ctrl-Break, poetomu mozhet  vypolnyat'sya
procedura obrabotki Ctrl-Break [3.2.8].  Vvedennyj simvol vozvra-
shchaetsya v AL. Pri vvode rasshirennogo koda AL soderzhit ASCII 0. Dlya
polucheniya v AL vtorogo  bajta  rasshirennogo  koda  nado povtorit'
preryvanie.


;---poluchenie vvedennogo simvola
   MOV  AH,1           ;nomer funkcii
   INT  21H            ;ozhidaem nazhatiya klavishi
   CMP  AL,0           ;rasshirennyj kod?
   JE   EXTENDED_CODE  ;esli da, to na spec. proceduru
    .                  ;inache simvol nahoditsya v AL

;---procedura obrabotki rasshirennyh kodov
      INT  21H            ;poluchaem v AL nomer koda
      CMP  AL,77          ;proverka na "kursor-vpravo"
      JNE  C_R            ;esli net, proverka sleduyushchego
      JMP  CURSOR_RIGHT   ;esli da, to na proceduru
C_R:  CMP  AL,75          ;... i t.d.

   |ta funkciya polnost'yu ignoriruet klavishu <ESC>.  Klavisha tabu-
lyacii interpretiruetsya  normal'no.  Klavisha zaboj sdvigaet kursor
na  odnu poziciyu vlevo, no simvol, nahodyashchijsya v etoj pozicii  ne
stiraetsya. Klavisha <Enter>  vyzyvaet peremeshchenie kursora v pervuyu
poziciyu tekushchej stroki (net avtomaticheskogo perevoda stroki).





   Nekotorye  programmy,  rabotayushchie v real'nom vremeni ne  mogut
ostanavlivat'sya i zhdat' nazhatiya klavishi;  oni prinimayut simvol iz
bufera klaviatury tol'ko v te momenty, kogda eto udobno dlya prog-
rammy. Naprimer, bezdejstvie processora vo vremya ozhidaniya vvoda s
klaviatury  ostanovilo by vse dejstviya na ekrane v igrovoj  prog-
ramme. Napomnim, chto legko proverit' pust ili net bufer klaviatu-
ry, ispol'zuya metody, opisannye v [3.1.2].

   Vysokij uroven'.

   Nado prosto ispol'zovat' INKEY$, ne pomeshchaya ego v cikl:

100 C$=INKEY$          'poluchenie simvola
110 IF C$ <> "" THEN...'esli simvol vveden, to ...
120 ...                'inache net simvola v bufere

   Srednij uroven'.

   Funkciya  6 preryvaniya 21H - eto edinstvennyj  sposob  poluchit'
vvedennyj simvol bez ozhidaniya. |ta funkciya ne daet eha na ekran i
ne  raspoznaet Ctrl-Break.  Pered vyzovom preryvaniya v DL  dolzhno
byt' pomeshcheno 0FFH. V protivnom sluchae funkciya 6 sluzhit sovershen-
no  protivopolozhnoj  celi - pechataet v  tekushchej  pozicii  kursora
simvol, nahodyashchijsya v DL.  Flag  nulya  ustanavlivaetsya  v 1, esli
bufer klaviatury pust. Esli simvol prinyat, to on pomeshchaetsya v AL.
Kod ASCII 0  indiciruet  rasshirennyj  kod  i dlya polucheniya nomera
koda preryvanie dolzhno byt' povtoreno.

           MOV  AH,6           ;nomer funkcii DOS
           MOV  DL,0FFH        ;zapros vvoda s klaviatury
           INT  21H            ;poluchenie simvola
           JZ   NO_CHAR        ;perehod esli net simvola
           CMP  AL,0           ;proverka na rasshirennyj kod
           JE   EXTENDED_CODE  ;esli da, to na spec. proceduru
           ...                 ;inache v AL kod ASCII

EXTENDED_CODE:   INT 21H       ;poluchaem nomer rasshirennogo koda
                 ...           ;nomer koda v AL





   I  Bejsik  i MS DOS predostavlyayut procedury dlya priema  stroki
simvolov.  Oni  avtomaticheski  povtoryayut  procedury  vvoda odnogo
simvola,  opisannye v predydushchih razdelah, ozhidaya vvoda  vozvrata
karetki, signaliziruyushchego  okonchanie  stroki. Konechno dolzhna byt'
otvedena  pamyat', dostatochnaya dlya priema vseh simvolov stroki,  i
dolzhna zapisyvat'sya dlina kazhdoj  stroki dlya togo, chtoby otdelit'
odnu stroku ot drugoj.  |to delaetsya s pomoshch'yu deskriptorov stro-
ki, kotorye sostoyat iz odnogo ili  bolee bajtov, soderzhashchih adres
i/ili dlinu stroki. V Bejsike pervye dva bajta deskriptora stroki
soderzhat adres stroki, a  sami  deskriptory  hranyatsya  v  massive
otdel'no ot strok.  Dlina stroki hranitsya v tret'em bajte 3-bajt-
nogo deskriptora. S drugoj storony, DOS hranit dlinu stroki pryamo
v  nachale samoj stroki i dlya programmy dostatochno znat' polozhenie
stroki v pamyati.

   Vysokij uroven'.

   Bejsik mozhet prinimat' s i bez avtomaticheskogo  eha na ekrane.
Bolee  prosto  delaetsya  vvod  s ehom,  tak  kak  on  vypolnyaetsya
vstroennoj funkciej vvoda stroki INPUT. INPUT avtomaticheski sobi-
raet vvodimye simvoly, vyvodya ih na ekran po mere polucheniya.  Pri
nazhatii klavishi <Enter> vvod  zavershaetsya i znachenie stroki pris-
vaivaetsya  ukazannoj peremennoj (posylaemyj klavishej <Enter>  kod
ASCII 13 ne dobavlyaetsya k  stroke).   INPUT dopuskaet vozmozhnost'
redaktirovaniya  stroki,  predostavlyaemuyu  DOS,  poetomu  opechatki
mogut byt' ispravleny pered vvodom  stroki. INPUT prinimaet chisla
v  vvide stroki i avtomaticheski preobrazuet ih v chislovuyu  formu,
esli dlya vvoda budet ukazano  imya  chislovoj  peremennoj. Nakonec,
INPUT  mozhet vydavat' na ekran stroku, zaprashivayushchuyu pol'zovatelya
o trebuemoj informacii.   Takaya  stroka  mozhet byt' dlinoj do 254
simvolov.  Esli ee dlina bol'she, to lishnie simvoly  ignoriruyutsya.
Osnovnaya forma etogo  operatora  INPUT  "zapros", imya_peremennoj.
Polnoe opisanie etogo opertora sm. v rukovodstve po Bejsiku.

110 INPUT "Enter your name: ",NAME$  'prinimaet imya kak stroku
120 INPUT "Enter your age: ",AGE%    'prinimaet vozrast kak chislo

   Operator  INPUT  neadekvaten,  kogda v vvodimoj  stroke  mogut
vstrechat'sya rasshirennye kody, takie  kak kody upravleniya kursorom
v  polnoekrannom  tekstovom redaktore.  V etom  sluchae  trebuetsya
ispol'zovat' funkciyu  INKEY$  dlya  priema  kazhdogo simvola, zatem
proveryat'  vvod na rasshirennye kody, vydelyat' simvoly  upravleniya
kursorom, takie kak vozvrat  karetki,  i tol'ko posle etogo vyvo-
dit'  na  ekran te simvoly, kotorye sleduet vyvodit'.   Pri  etom
upravlyayushchie simvoly takzhe vklyuchayutsya  po odnomu v konec strokovoj
peremennoj.  Tekstovye fajly predstavlyayut soboj nabor takih stro-
kovyh peremennyh. V punkte  [3.1.8]  Vy najdete proceduru vvoda s
klaviatury, v kotoroj funkciya INKEY$ ispo'zuetsya ukazannym  obra-
zom.


   Srednij uroven'.

   Funkciya 0AH preryvaniya 21H  pozvolyaet vvodit' stroku dlinoj do
254 simvolov, vydavaya eho na terminal.  |ta procedura  prodolzhaet
vvod postupayushchih  simvolov  do  teh  por,  poka ne nazhata klavisha
vozvrat  karetki.  DS:DX ukazyvaet na adres pamyati,  kuda  dolzhna
byt' pomeshchena stroka. Pri vhode pervyj bajt v etoj pozicii dolzhen
soderzhat' chislo bajtov, otvodimyh dlya etoj stroki. Posle togo kak
stroka vvedena, vtoroj bajt  dast  chislo real'no vvedennyh simvo-
lov. Sama stroka nachinaetsya s tret'ego bajta.
   Nado  otvesti  dostatochno pamyati dlya stroki nuzhnoj dliny  plyus
dva bajta dlya deskriptora stroki i odin dobavochnyj bajt dlya vozv-
rata karetki. Kogda Vy ustanavlivaete maksimal'nuyu dlinu stroki v
pervom bajte, to ne zabud'te dobavit' 1 dlya vozvrata karetki. Kod
vozvrata karetki - ASCII 13 - vvoditsya kak poslednij simvol stro-
ki, no on ne uchityvaetsya v  rezul'tate,  kotoryj funkciya pomeshchaet
vo vtoroj bajt deskriptora stroki.  Takim obrazom, dlya  polucheniya
50-simvol'noj stroki nado  otvesti  53 bajta pamyati i pomestit' v
pervyj  bajt ASCII 51.  Posle vvoda 50 simvolov vtoroj bajt budet
soderzhat' ASCII 50, a 53-j bajt otvedennoj pamyati - ASCII 13.

;---v segmente dannyh
STRING   DB   53 DUP(?)     ;oblast' dlya stroki 50 simvolov

;---poluchenie stroki s klaviatury
         LEA  DX,STRING     ;DS:DX ukazyvayut na adres stroki
         MOV  BX,DX         ;pust' BX tozhe ukazyvaet na stroku
         MOV  AL,51         ;ustanovka dliny stroki (+1 dlya CR)
         MOV  [BX],AL       ;posylaem v 1-j bajt deskriptora
         MOV  AH,0AH        ;nomer funkcii
         INT  21H           ;poluchaem stroku
;---proverka dliny stroki
         MOV  AH,[BX]+1     ;teper' dlina v AH

   V etoj procedure mozhno ispol'zovat' vozmozhnosti redaktirovaniya
stroki MS DOS.  Nazhatie klavishi zaboj ili "strelka-vlevo" udalyaet
simvol s ekrana, a takzhe ne pomeshchaet ego v pamyat'.  Rabotaet kla-
visha  tabulyacii,  rasshirennye kody  ignoriruyutsya,  pustye  stroki
dopuskayutsya (imeetsya vvidu vozvrat karetki, kotoromu ne predshest-
vuet drugogo simvola).  Na terminale pri dostizhenii pravogo  kraya
stroka perenositsya na sleduyushchuyu  stroku, a pri dostizhenii pravogo
nizhnego  ugla ekran sdvigaetsya na stroku vverh.   Kogda  vvoditsya
bol'she simvolov, chem otvedeno mesta dlya stroki, to lishnie simvoly
ignoriruyutsya i vklyuchaetsya gudok dinamika.
   MS  DOS  obespechivaet  i drugoj sposob polucheniya  stroki,  pri
kotorom ne vyvoditsya eho na terminal.  Funkciya 3FH preryvaniya 21H
- eto funkciya vvoda obshchego naznacheniya, kotoraya chashche vsego ispol'-
zuetsya  pri  diskovyh operaciyah.  Ona  trebuet  predopredelennogo
deskriptora fajla (file handle), kotoryj yavlyaetsya kodovym chislom,
ispol'zuemym  operacionnoj  sistemoj dlya  oboznacheniya  ustrojstva
vvoda/vyvoda. Dlya klavitury ispol'zuetsya deskriptor 0 i on dolzhen
byt'  pomeshchen v BX.  Pomestite v DS:DX adres, po kotoromu  dolzhna
nahodit'sya stroka, a v CX -  maksimal'nuyu dlinu stroki i vyzovite
funkciyu:


;---chtenie stroki bez eha
   MOV  AH,3FH            ;nomer funkcii
   MOV  BX,0              ;nomer deskriptora fajla
   LEA  DX,STRING_BUFFER  ;ukazatel' na bufer vvoda stroki
   MOV  CX,100            ;maksimal'naya dlina stroki
   INT  21H               ;zhdem vvoda

Vvod stroki zavershaetsya  nazhatiem  klavishi  vozvrat karetki i DOS
dobavlyaet  v konec stroki dva simvola: vozvrat karetki i  perevod
stroki (ASCII 13 i ASCII 10). Iz-za etih dobavochnyh simvolov, pri
ukazanii dliny stroki 100 simvolov ona mozhet zanimat' do 102 bajt
pamyati.  Dlina vvedennoj stroki  vozvrashchaetsya v AX i eto znachenie
vklyuchaet dva simvola-ogranichitelya.





   Dva   bajta,  raspolozhennye  v  yachejkah  pamyati  0040:0017   i
0040:0018 soderzhat bity, otrazhayushchie  status klavishi sdviga i dru-
gih klavish-pereklyuchatelej sleduyushchim obrazom:

            Bit    Klavisha      Znachenie, kogda bit = 1
0040:0017    7     Insert       rezhim vstavki vklyuchen
             6     CapsLock     rezhim CapsLock vklyuchen
             5     NumLock      rezhim NumLock vklyuchen
             4     ScrollLock   rezhim ScrollLock vklyuchen
             3     Alt          klavisha nazhata
             2     Ctrl         klavisha nazhata
             1     levyj Shift  klavisha nazhata
             0     pravyj Shift klavisha nazhata

0040:0018    7     Insert       klavisha nazhata
             6     CapsLock     klavisha nazhata
             5     NumLock      klavisha nazhata
             4     ScrollLock   klavisha nazhata
             3     Ctrl-NumLock rezhim Ctrl-NumLock vklyuchen
ostal'nye bity ne ispol'zuyutsya

   Preryvanie  klaviatury nemedlenno obnovlyaet eti bity  statusa,
kak tol'ko budet nazhata odna iz klavish-pereklyuchatelej,  dazhe esli
ne bylo schitano ni odnogo simvola iz bufera klaviatury. |to verno
i dlya klavishi Ins, kotoraya edinstvennaya iz etih 8 klavish pomeshchaet
kod  v bufer (ustanovka statusa Ins menyaetsya dazhe  esli v  bufere
net mesta dlya  simvola).  Otmetim,  chto bit 3 po adresu 0040:0018
ustanavlivaetsya v 1, kogda dejstvuet rezhim zaderzhki Ctrl-NumLock;
poskol'ku v etom sostoyanii  programma priostanovlena, to etot bit
nesushchestvenen.
   Preryvanie  klaviatury  proveryaet  sostoyanie  statusnyh  bitov
pered tem, kak interpretirovat'  nazhatye  klavishi,  poetomu kogda
programma menyaet odin iz etih bitov, to effekt takoj zhe, kak  pri
fizicheskom nazhatii  sootvetstvuyushchej  klavishi.  Vy mozhete zahotet'
ustanovit'  sostoyanie klavish NumLock i CapsLock, chtoby byt'  uve-
rennym, chto vvod budet trebuemogo vida.  Naoborot, Vasha programma
mozhet nuzhdat'sya v chtenii statusa etih klavish, naprimer dlya  togo,
chtoby vyvesti tekushchij status na ekran. Otmetim, chto klaviatura AT
pravil'no  ustanavlivaet  svetovye indikatory  sostoyaniya  klavish,
dazhe esli pereklyucheny programmno.

   Vysokij uroven'.

   V  dannom  primere klavisha NumLock perevoditsya v rezhim,  kogda
klavishi dopolnitel'noj  klaviatury  ispol'zuyutsya  dlya peremeshcheniya
kursora, za schet sbrasyvaniya bita 5 po adresu 0040:0017 v 0.  |to
dostigaetsya za schet operacii  logicheskogo  "I" znacheniya, raspolo-
zhennogo  po etomu adresu s chislom 223 (cepochka bitov 11011111B  -
opisanie logiki bitovyh  operacij  sm. v Prilozhenii B). Rezul'tat
pomeshchaetsya  v  bajt statusa.  V primere  zatem  vosstanavlivaetsya
znachenie etogo bita  v  1,  za   schet   logicheskogo  "ILI"  s  32
(00100000B).


100 DEF SEG = &H40             'ustanavlivaem segment na oblast'
110 STATUSBYTE=PEEK(&H17)      'BIOS i berem bajt statusa
120 NEWBYTE=STATUSBYTE AND 223 'obnulyaem bit 5
130 POKE(&H17,NEWBYTE)         'posylaem novoe znachenie statusa

CHtoby, naoborot, vklyuchit' etot bit:

120 NEWBYTE=STATUSBYTE OR 32   'ustanavlivaem bit 5
130 POKE(&H17,NEWBYTE)         'posylaem novoe znachenie statusa

Stroki 110-130 mogut byt' uplotneny k vidu:

110 POKE(&H417,PEEK(&H417)AND 223)
   ili
110 POKE(&H417,PEEK(&H417)OR 223)

   Srednij uroven'.

   Funkciya  2 preryvaniya 16H predostavlyaet dostup k  odnomu -  no
tol'ko odnomu - iz bajtov statusa.  |to bajt po adresu 0040:0017,
kotoryj soderzhit bol'she poleznoj informacii.  Bajt vozvrashchaetsya v
AL.

;---proverka statusa klavishi vstavki
   MOV  AH,2           ;nomer funkcii
   INT  16H            ;poluchaem bajt statusa
   TEST AL,10000000B   ;proveryaem bit 7
   JZ   INSERT_OFF     ;esli 0, to INSERT vyklyuchen

   Nizkij uroven'.

   V dannom primere  ustanavlivaetsya rezhim vstavki, za schet usta-
novki bita 7 bajta statusa po adresu 0040:0017 (kotoryj adresuet-
sya kak 0000:0417).

   SUB  AX,AX            ;ustanavlivaem dobavochnyj segment na
   MOV  ES,AX            ;nachalo pamyati
   MOV  AL,10000000B     ;gotovim bit 7 k ustanovke
   OR   ES:[417H],AL     ;menyaem bajt statusa





   Sistema  kodov, ispol'zuemyh klaviaturoj, ne poddaetsya prostoj
intrepretacii. Kody mogut imet' dlinu 1 ili 2 bajta i net prosto-
go sootvetstviya mezhdu dlinoj koda i tem, sluzhit li on dlya obozna-
cheniya simvola ili dlya upravleniya oborudovaniem. Ne vse kombinacii
klavish dazhe vydayut unikal'nyj kod, poetomu neobhodimy  dobavochnye
usiliya, chtoby razlichit' ih. Ni kody ASCII, ni rasshirennye kody ne
uporyadocheny takim obrazom, kotoryj by pozvolil ih prostuyu gruppi-
rovku i proverku oshibok. Drugimi  slovami, procedura vvoda s kla-
viatury obshchego naznacheniya trebuet hlopotlivogo programmirovaniya.
   Zdes' privedeny primery na Bejsike i s ispol'zovaniem preryva-
niya 16H. V nih pokazano kak svesti vmeste bol'shinstvo informacii,
privedennoj v dannoj glave. Obshchij algoritm pokazan na ris. 3-3.

   Vysokij uroven'.

   Procedura obrabotki vvoda s klaviatury, napisannaya na Bejsike,
mozhet delat' vse  chto  delaet  assemblernaya  procedura,  za odnim
isklyucheniem.  Funkciya INKEY$ ne predostavlyaet dostupa k  skan-ko-
dam. |to oznachaet, chto  Vy  ne  mozhete  skazat'  polucheny li kody
ASCII 8, 9, 13 i 27 ot nazhatiya klavish <BackSpace>, <Tab>, <Enter>
i <Escape> ili cherez Ctrl-H,  -I,  -M  i -[.  Razlichie mozhet byt'
ustanovleno  proverkoj  bita  statusa  klavishi  Ctrl,  po  adresu
0040:0017, v moment nazhatiya klavishi. No etot metod ne budet rabo-
tat',  esli  vvedennyj simvol byl zapasen v bufere  klaviatury  v
techenie nekotorogo vremeni.

100 C$=INKEY$:IF C$="" THEN 100   'poluchenie simvola
110 IF LEN(C$)=2 THEN 700         'esli rasshirennyj, to na 700
120 C=ASC(C$)                     'inache berem nomer koda ASCII
130 IF C<32 THEN 300              'esli upravlyayushchij, to na 300
140 IF C<65 OR C>123 THEN 100     'prinimaem tol'ko simvoly
150 '''pishushchej mashinki i delaem s nimi, chto hotim, naprimer:
160 S$=S$+C$                      'dobavlyaem simvol k stroke
170 PRINT C$;                     'vyvodim ego na ekran
180 '''... i t.d.
190 GOTO 100                      'na vvod sleduyushchego simvola
 .
 .
300 '''procedura obrabotki upravlyayushchih kodov ASCII
310 DEF SEG = 0                   'ukazyvaem na nachalo pamyati
320 REGISTER=PEEK(&H417)          'berem registr statusa
330 X=REGISTER AND 4              'X=4, kogda nazhat Ctrl
340 IF X=0 THEN 500               'esli ne nazhat, to na 500
350 '''esli eto kombinaciya Ctrl-bukva, to delaem chto hotim
360 IF C=8 THEN GOSUB 12000       'naprimer, perehodim na proce-
370 '''duru vyvoda ekrana pomoshchi i t.d.
380 GOTO 100                      'na vvod sleduyushchego simvola
 .
 .


500 '''procedura obrabotki 4-h klavish: dekodiruet kody ASCII 8,
510 '''9, 13 i 27, kogda klavisha Ctrl ne nazhata
520 IF C=8 THEN GOSUB 5000        'obrabotka <BackSpace>
530 IF C=9 THEN GOSUB 6000        'obrabotka <Tab>
540 IF C=13 THEN GOSUB 7000       'obrabotka <CR>
550 IF C=27 THEN GOSUB 8000       'obrabotka <Esc>
560 GOTO 100                      'na vvod sleduyushchego simvola
 .
 .
700 '''procedura obrabotki rasshirennyh kodov
710 C$=RIGHT$(C$,1)               'berem tol'ko 2-j bajt C$
720 C=ASC(C$)                     'perevodim v chislovuyu formu
730 '''v C - rasshirennyj kod - delaem s nim, chto hotim, naprimer
740 IF C<71 OR C>81 THEN 100   'berem tol'ko upravlenie kursorom
750 IF C=72 THEN GOSUB 3500    'obrabotka "kursor-vverh"
760 '''... i t.d.
770 GOTO 100                      'na vvod sleduyushchego simvola

   Srednij uroven'.

   |tot  primer  otlichaetsya ot predydushchego metodom  raspoznavaniya
chetyreh chastnyh sluchaev Ctrl-H, -I,  -M i -[. Zdes', kogda vstaet
vopros o tom, voznik li ukazannyj kod pri nazhatii odnoj  klavishi,
ili v kombinacii s  klavishej  Ctrl,  proveryaetsya  skan-kod.  |tot
metod bolee pravilen, chem proverka bita statusa, tak kak skan-kod
zapominaetsya v bufere  klaviatury, a ustanovka bita statusa mozhet
byt' izmenena.

;---poluchenie koda nazhatoj klavishi i opredelenie ego tipa
NEXT:  MOV  AH,0           ;funkciya vvoda s klaviatury BIOS
       INT  16H            ;poluchaem vvedennyj kod
       CMP  AL,0           ;proverka na rasshirennyj kod
       JE   EXTENDED_CODE  ;esli da, to na spec. proceduru
       CMP  AL,32          ;proverka na upravlyayushchij simvol
       JL   CONTROL_CODE   ;esli da, to na spec. proceduru
       CMP  AL,65          ;esli simvol ne vhodit v nabor pishu-
       JL   NEXT           ;shchej mashinki, to berem sleduyushchij
       CMP  AL,123         ;
       JL   NEXT           ;
;---teper' obrabatyvaem simvol v AL
       STOSB               ;zapominaem simvol po adresu ES:DI
       MOV  AH,2           ;funkciya vyvoda simvola na ekran
       MOV  DL,AL          ;pomeshchaem simvol v DL pered vyvodom
       INT  21H            ;vyvodim ego na ekran
        .
        .
       JMP  NEXT           ;perehodim k sleduyushchemu simvolu


;---analiziruem upravlyayushchie kody
CONTROL_CODE:  CMP  AL,13       ;kod ASCII 13?
               JNE  TAB         ;esli net, to sled. proverka
               CMP  AH,28       ;inache proveryaem skan-kod <CR>
               JNE  C_M         ;esli net, to bylo Ctrl-M
               CALL CARRIAGE_RET;obrabotka vozvrata karetki
               JMP  NEXT        ;perehod k sleduyushchemu simvolu
C_M:           CALL CTRL_M      ;obrabotka Ctrl-M
               JMP  NEXT        ;perehod k sleduyushchemu simvolu
TAB:           CMP  AL,9        ;proverka na tabulyaciyu...
                .
                .
               CMP  AL,10       ;zatem proverka drugih
                .
                .
REJECT:        JMP  NEXT        ;perehod k sleduyushchemu simvolu
;---analiz rasshirennyh kodov (2-j bajt koda v AH):
EXTENDED_CODE: CMP  AH,71       ;proverka nizhnej granicy
               JL   REJECT      ;esli men'she, to sled. simvol
               CMP  AH,81       ;proverka verhnej granicy
               JL   REJECT      ;esli bol'she, to sled. simvol
;---AH soderzhit simvol upravleniya kursorom, analiziruem ego:
               CMP  AH,72       ;"kursor-vverh"?
               JE   C_U         ;esli da, to na proceduru
               CMP  AH,80       ;"kursor-vniz"?
               JE   C_D         ;esli da, to na proceduru
                .
                .
C_U:           CALL CURSOR_UP   ;vyzov sootvetstvuyushchej procedury
               JMP  NEXT        ;perehod k sleduyushchemu simvolu
C_D:           CALL CURSOR_DOWN ;vyzov sootvetstvuyushchej procedury
               JMP  NEXT        ;perehod k sleduyushchemu simvolu





   Kogda  mikroprocessor  klaviatury pomeshchaet skan-kod v  port  A
mikroshemy 8255 (adres  porta  60H  -  sm.  [1.1.1]), to pri etom
vyzyvaetsya preryvanie 9.  Zadacha etogo preryvaniya - preobrazovat'
skan-kod simvola, osnovyvayas' na sostoyanii klavish-pereklyuchatelej,
i pomestit' ego v bufer klaviatury.  (Esli skan-kod sootvetstvuet
klavishe-pereklyuchatelyu, to v  bufer  klaviatury ne pishetsya nichego,
za  isklyucheniem sluchaya klavishi <Ins>, a vmesto  etogo  preryvanie
izmenyaet  bajty  statusa,  raspolozhennye  v  oblasti  dannyh BIOS
[3.1.7]).   Preryvaniya  "vvoda s klaviatury" DOS i BIOS na  samom
dele vsego lish' preryvaniya "vvoda iz bufera klaviatury". Na samom
dele oni ne raspoznayut nazhatiya klavish. Tochnee, oni chitayut interp-
retaciyu vvedennyh klavish, kotoruyu  obespechilo preryvanie 9. Zame-
tim,  chto  PCjr ispol'zuet special'nuyu proceduru  (INT  48H)  dlya
preobrazovaniya vvoda ot ego 62  klavish k 83-klavishnomu protokolu,
ispol'zuemomu drugimi IBM PC. Rezul'tat etoj procedury peredaetsya
preryvaniyu 9, kotoroe vypolnyaet svoyu rabotu kak obychno.  Preryva-
niem  49H  PCjr obespechivaet special'nye  neklavishnye  skan-kody,
kotorye potencial'no  mogut  ustanavlivat'sya  periferijnymi  ust-
rojstvami,  ispol'zuyushchimi  infrakrasnuyu (besprovolochnuyu) svyaz'  s
klaviaturoj.
   Trebuetsya ves'ma neobychnoe  primenenie,  chtoby imelo smysl pe-
reprogrammirovat'  eto preryvanie, osobenno uchityvaya, chto MS  DOS
pozvolyaet  Vam   pereprogrammirovat'   lyubuyu   klavishu klaviatury
[3.2.6].  Esli vse zhe Vam pridetsya pereprogrammirovat' preryvanie
9, to eta glava dast Vam osnovy dlya  starta.  Snachala nado prochi-
tat'  [1.2.3], chtoby ponimat' kak programmiruyutsya preryvaniya.   V
preryvanii klaviatury mozhno vydelit' tri osnovnyh shaga:

   1.  Prochitat' skan-kod i poslat' klaviature podtverdayushchij sig-
nal.
   2. Preobrazovat' skan-kod v nomer koda ili v ustanovku oegist-
ra statusa klavish-pereklyuchatelej.
   3. Pomestit' kod klavishi v bufer klaviatury.

   V  moment vyzova preryvaniya skan-kod budet nahodit'sya v  porte
A.  Poetomu snachala nado etot kod prochitat' i sohranit' na steke.
Zatem ispol'zuetsya port B (adres 61H),  chtoby bystro poslat' sig-
nal podtverzhdeniya mikroprocessoru klaviatury. Nado prosto ustano-
vit' bit 7 v 1, a zatem srazu  izmenit'  ego  nazad v 0. Zametim,
chto bit 6 porta B upravlyaet signalom chasov klaviatury.  On vsegda
dolzhen byt' ustanovlen v 1, inache klaviatura budet vyklyuchena. |ti
adresa  portov  primenimy i k AT, hotya on i ne  imeet  mikroshemy
interfejsa s periferiej 8255.
   Snachala skan-kod analiziruetsya na predmet togo, byla li klavi-
sha nazhata (kod nazhatiya) ili otpushchena (kod osvobozhdeniya).  Na vseh
mashinah, krome AT, kod osvobozhdeniya  indiciruetsya ustanovkoj bita
7  skan-koda  v 1.  Dlya AT, u kotorogo bit 7 vsegda raven 0,  kod
osvobozhdeniya sostoit  iz  dvuh  bajtov:  snachala  0F0H,  a  zatem
skan-kod.  Vse kody osvobozhdeniya otbrasyvayutsya, krome sluchaya kla-
vish-pereklyuchatelej, dlya kotoryh  delayutsya sootvetstvuyushchie izmene-
niya v bajtah ih statusa. S drugoj storony, vse kody nazhatiya obra-
batyvayutsya. Pri etom  opyat'  mogut  izmenyat'sya bajty statusa kla-


vish-pereklyuchatelej.  V sluchae zhe simvol'nyh kodov, nado proveryat'
bajty statusa, chtoby opredelit', naprimer,  chto skan-kod 30 soot-
vetstvuet nizhnemu ili verhnemu registru bukvy A.
   Posle  togo  kak vvedennyj simvol  identificirovan,  procedura
vvoda s klaviatury dolzhna najti sootvetstvuyushchij emu kod ASCII ili
rasshirennyj kod.  Privedennyj primer slishkom korotok, chtoby  ras-
smotret'  vse  sluchai.  V obshchem sluchae  skan-kody  sopostavlyayutsya
elementam tablicy dannyh, kotoraya analiziruetsya instrukciej XLAT.
XLAT prinimaet v AL chislo ot 0 do 255, a vozvrashchaet v AL  1-bajt-
noe znachenie iz 256-bajtnoj  tablicy, na kotoruyu ukazyvaet DS:BX.
Tablica mozhet nahodit'sya v segmente dannyh.  Esli v AL  nahodilsya
skan-kod 30, to tuda budet pomeshchen iz tablicy bajt nomer 30 (31-j
bajt,  tak  kak otschet nachinaetsya s nulya).  |tot  bajt v  tablice
dolzhen byt' ustanovlen ravnym 97, davaya kod ASCII dlya "a". Konech-
no  dlya  polucheniya zaglavnoj A nuzhna  drugaya  tablica, k  kotoroj
obrashchenie budet proishodit', esli  status sdviga ustanovlen.  Ili
zaglavnye bukvy mogut hranit'sya v drugoj chasti toj zhe tablicy, no
v etom sluchae k skan-kodu nado budet  dobavlyat' smeshchenie, oprede-
lyaemoe statusom klavish-pereklyuchatelej.
   Nakonec, nomera kodov dolzhny byt' pomeshcheny v bufer klaviatury.
Procedura dolzhna snachala proverit', imeetsya li v bufere mesto dlya
sleduyushchego  simvola.  V [3.1.1] pokazano, chto etot bufer  ustroen
kak ciklicheskaya ochered'. YAchejka  pamyati 0040:001A soderzhit ukaza-
tel'  na  golovu bufera, a 0040:001C - ukazatel' na  hvost.   |ti
slovnye ukazateli dayut smeshchenie  v  oblasti  dannyh BIOS (kotoraya
nachinaetsya  v segmente 40H) i nahodyatsya v diapazone ot 30 do  60.
Novye simvoly vstavlyayutsya v yachejki  bufera s bolee starshimi adre-
sami,  a  kogda dostignuta verhnyaya granica, to  sleduyushchij  simvol
perenositsya v nizhnij konec  bufera.  Kogda bufer polon, to ukaza-
tel' hvosta na 2 men'she ukazatelya na golovu - krome sluchaya, kogda
ukazatel' na golovu raven  30  (nachalo  oblasti bufera), a v etom
sluchae bufer polon, kogda ukazatel' hvosta raven 60.
   Dlya  vstavki simvola v bufer, nado pomestit' ego v poziciyu, na
kotoruyu ukazyvaet hvost bufera i zatem uvelichit' ukazatel' hvosta
na  2; esli ukazatel' hvosta byl raven 60, to nado  izmenit'  ego
znachenie na 30. Vot i vse.  Shema  preryvaniya klaviatury pokazana
na ris. 3-4.

   Nizkij uroven'.

   |ffektivnaya  procedura trebuet glubokogo produmyvaniya.  V etom
primere dany tol'ko samye  zachatki.  On prinimaet tol'ko bukvy na
nizhnem  i verhnem registrah, prichem vse oni zagruzheny v odnu tab-
licu, v kotoroj bukvy  verhnego  registra  nahodyatsya  na 100 bajt
vyshe, chem ih mladshie brat'ya.  Analiziruetsya tol'ko levaya  klavisha
sdviga i tekushchee sostoyanie klavishi CapsLock ignoriruetsya.

;---v segmente dannyh
TABLE   DB   16 DUP(0)            ;propuskaem 1-e 16 bajt
        DB   'qwertyuiop',0,0,0,0 ;verhnij ryad klaviatury
        DB   'asdfghjkl',0,0,0,0,0 ;srednij ryad klaviatury
        DB   'zxcvbnm'            ;nizhnij ryad klaviatury
        DB   16 DUP(0)            ;propusk do verhnego registra
        DB   'QWERTYUIOP',0,0,0,0 ;te zhe simvoly na verhnem
        DB   'ASDFGHJKL',0,0,0,0,0 ;registre
        DB   'ZXCVBNM'            ;


;---v nachale programmy ustanavlivaem preryvanie
        CLI                       ;zapret preryvanij
        PUSH DS                   ;sohranyaem registr
        MOV  AX,SEG NEW_KEYBOARD  ;DS:DX dolzhny ukazyvat' na
        MOV  DS,AX                ;proceduru obrabotki
        MOV  DX,OFFSET NEW_KEYBOARD ;preryvaniya
        MOV  AL,9                 ;nomer vektora preryvaniya
        MOV  AH,25H               ;nomer funkcii DOS
        INT  21H                  ;menyaem vektor preryvaniya
        POP  DS                   ;vosstanavlivaem registr
        STI                       ;razreshaem preryvaniya

Programma prodolzhaetsya, zatem ostavayas' rezidentnoj [1.3.4].

;---eto samo preryvanie klaviatury
NEW_KEYBOARD  PROC FAR         ;sohranyaem vse izmenyaemye
              PUSH AX          ;registry
              PUSH BX          ;
              PUSH CX          ;
              PUSH DI          ;
              PUSH ES          ;
;---poluchaem skan-kod i posylaem signal podtverzhdeniya
   IN   AL,60H         ;poluchaem skan-kod iz porta A
   MOV  AH,AL          ;pomeshchaem kopiyu v AH
   PUSH AX             ;sohranyaem skan-kod
   IN   AL,61H         ;chitaem sostoyanie porta B
   OR   AL,10000000B   ;ustanavlivaem bit 7
   OUT  61H,AL         ;posylaem izmenennyj bajt v port
   AND  AL,01111111B   ;sbrasyvaem bit 7
   OUT  61H,AL         ;vozvrashchaem sostoyanie porta B
;---ES dolzhen ukazyvat' na oblast' dannyh BIOS
   MOV  AX,40H         ;ustanavlivaem segment
   MOV  ES,AX          ;
   POP  AX             ;vozvrashchaem skan-kod iz steka
;---proverka klavishi sdviga
         CMP  AL,42          ;nazhat levyj sdvig?
         JNE  KEY_UP         ;net - smotrim sleduyushchee
         MOV  BL,1           ;da - izmenyaem bit statusa
         OR   ES:[17H],BL    ;menyaem pryamo registr statusa
         JMP  QUIT           ;vyhod iz procedury
KEY_UP:  CMP  AL,170         ;levyj sdvig otpushchen?
         JNE  NEXTKEY        ;net - smotrim sleduyushchee
         MOV  BL,11111110B   ;da - menyaem bit statusa
         AND  ES:[17H],BL    ;menyaem pryamo registr statusa
         JMP  QUIT           ;vyhod iz procedury
NEXTKEY:                     ;prosmotr drugih pereklyuchatelej
;---eto simvol'naya klavisha - interpretiruem skan-kod
             TEST AL,10000000B  ;kod osvobozhdeniya klavishi?
             JNZ  QUIT          ;da - vyhodim iz procedury
             MOV  BL,ES:[17H]   ;inache berem bajt statusa
             TEST BL,00000011B  ;klavisha sdviga nazhata?
             JZ   CONVERT_CODE  ;net - uhodim dal'she
             ADD  AL,100        ;da - znachit zaglavnaya bukva
CONVERT_CODE:  MOV  BX,OFFSET TABLE  ;gotovim tablicu
             XLAT TABLE         ;preobrazuem skan-kod v ASCII
             CMP  AL,0          ;vozvrashchen 0?
             JE   QUIT          ;esli da, to na vyhod


;---kod klavishi gotov, proveryaem ne polon li bufer klaviatury
             MOV  BX,1AH        ;smeshchenie ukazatelya na golovu
             MOV  CX,ES:[BX]    ;poluchaem ego znachenie
             MOV  DI,ES:[BX]+2  ;poluchaem ukazatel' hvosta
             CMP  CX,60         ;golova na vershine bufera?
             JE   HIGH_END      ;da - perehodim k spec. sluchayu
             INC  CX            ;uvelichivaem ukazatel' golovy
             INC  CX            ;na 2
             CMP  CX,DI         ;sravnivaem s ukazatelem hvosta
             JE   QUIT          ;esli ravny, to bufer polon
             JMP  GO_AHEAD      ;inache vstavlyaem simvol
HIGH_END:    CMP  DI,30         ;proverka spec. sluchaya
             JE   QUIT          ;esli bufer polon, to vyhod
;---bufer ne polon - vstavlyaem v nego simvol
GO_AHEAD:    MOV  ES:[DI],AL    ;pomeshchaem simvol v poziciyu hvosta
             CMP  DI,60         ;hvost v konce bufera?
             JNE  NO_WRAP       ;esli net, to dobavlyaem 2
             MOV  DI,28         ;inache ukazatel' hvosta = 28+2
NO_WRAP:     ADD  DI,2          ;poluchaem novoe znachenie hvosta
             MOV  ES:[BX]+2,DI  ;posylaem ego v oblast' dannyh
;---zavershenie preryvaniya
QUIT:        POP  ES            ;vosstanavlivaem izmenyaemye
             POP  DI            ;registry
             POP  CX            ;
             POP  BX            ;
             POP  AX            ;
             MOV  AL,20H        ;vydaem signal ob okonchanii
             OUT  20H,AL        ;apparatnogo preryvaniya
             IRET               ;vozvrat iz preryvaniya
NEW_KEYBOARD ENDP




   Procedura  obrabotki  nazhatiya klavishi dolzhna  proveryat'  massu
razlichnyh tipov  klavish  i  uslovij,  poskol'ku  kak odno-, tak i
dvuhbajtnye kody mogut poyavlyat'sya v kombinacii s klavishami-perek-
lyuchatelyami. Ne vse klavishi logicheski sgruppirovany, po tipu koda,
kotoryj im sootvetstvuet.  Naprimer, klavisha <Backspace>  generi-
ruet odnobajtnyj kod  ASCII,  a  klavisha  <Delete>  - dvuhbajtnyj
rasshirennyj kod.  Klavisha Ctlr generiruet odnobajtnyj kod,  kogda
ona ispol'zuetsya v sochetanii s  alfavitnymi klavishami i dvuhbajt-
nyj kod v ostal'nyh sluchayah.  |ti neregulyarnosti voznmkayut  iz-za
ogranichennosti nabora ASCII: preryvanie klaviatury sleduet sogla-
sheniyam ASCII, kogda vozmozhno, no kogda eto nevozmozhno vydaet svoi
(rasshirennye) kody.
   V dannom razdele perechisleny  razlichnye gruppy klavish, dany ih
kody i ukazany vstrechayushchiesya anomalii.  V bol'shinstve sluchaev eta
informaciya dostupna v menee udobnom  vide iz tablic kodov ASCII i
rasshirennyh  kodov,  privedennyh v razdele 3 etoj  glavy.   Zdes'
obsuzhdayutsya takzhe special'nye  svojstva,  pripisyvaemye otdel'nym
klavisham Bejsikom, a takzhe special'naya obrabotka, dlya interpreta-
cii otdel'nyh klavish (takih kak zaboj), primenyaemaya v preryvaniyah
DOS.





   Klavishi <BackSpace>, <Enter>, <Escape>  i <Tab> - edinstvennye
chetyre  nesimvol'nye klavishi, kotorye generiruyut odnobajtnye  ko-
dy ASCII. |ti kody soderzhatsya v nabore upravlyayushchih kodov [7.1.9],
kotorye  zanimayut pervye 32 koda v nabore ASCII.  |ti chetyre koda
mogut byt' polucheny takzhe kombinaciej bukvennyh klavish s klavishej
Ctrl:

   ASCII   8    BackSpace          Ctrl + H
   ASCII   9    Tab                Ctrl + I
   ASCII  13    Enter              Ctrl + M
   ASCII  27    Escape             Ctrl + [

V [3.2.2] pokazano kak razlichat' nazhatie odnoj klavishi i kombina-
ciyu s klavishej Ctrl.  Otmetim, chto obratnaya tabulyaciya, proizvodi-
maya  nazhatiem kombinacii <Shift> + <Tab>, vydaet rasshirennyj  kod
0;15.
   Nekotorye iz preryvanij obrabotki vvoda s klaviatury avtomati-
cheski interpretiruyut eti chetyre special'nyh koda. V Bejsike funk-
ciya INPUT reagiruet  na  <Backspace>,  <Tab>  i <Enter>.  Funkciya
INKEY$  ne interpretiruet ni odin iz upravlyayushchih kodov, poskol'ku
u nee net avtomaticheskogo eha na ekran.  Vsyu rabotu dolzhna vypol-
nyat' Vasha programma.  Napomnim, chto dlya upravleniya dvizheniem kur-
sora Bejsik predostavlyaet funkciyu TAB.  Iz preryvanij BIOS i DOS,
te  kotorye vydayut eho na terminal interpretiruyut  takzhe  klavishi
<BackSpace> i <Tab>.  Posle  togo  kak  eti kody interpretiruyutsya
sootvetstvuyushchim  obrazom, kody ASCII vse ravno  poyavlyayutsya v  AL,
posle chego oni mogut byt'  vklyucheny v stroku simvolov ili ignori-
rovany, v zavisimosti ot togo, chto trebuetsya.





   Tri tipa klavish-pereklyuchatelej zastavlyayut tol'ko drugie klavi-
shi  klaviatury generirovat' razlichnye kody.  Kak  pravilo,  takie
kombinacii generiruyut  rasshirennye  kody.   No v dvuh sluchayah oni
dayut  kody ASCII: (1) kogda ispol'zuetsya klavisha <Shift> s
klavishami
alfavitno-cifrovyh simvolov i  (2)  nazhatie  kombinacii klavish ot
Ctrl-A do Ctrl-Z daet ASCII kody ot 1 do 26. Vse ostal'nye kombi-
nacii dayut rasshirennye kody, perechislennye  v [3.3.5]. PCjr imeet
neskol'ko isklyuchenij, kotorye obsuzhdayutsya nizhe.
   Nedopustimye kombinacii klavish ne proizvodyat koda, voobshche.  Za
isklyucheniem sluchaya special'nyh kombinacij s Ctrl-Alt, odnovremen-
noe nazhatie neskol'kih pereklyuchatelej privodit k tomu, chto tol'ko
odin iz nih stanovitsya effektivnym, prichem prioritet u Alt, zatem
Ctrl, i zatem Shift. V [3.1.7] pokazano kak proverit' nazhata li v
dannyj  moment  klavisha-pereklyuchatel'.   V  [3.2.3] pokazano, kak
ispol'zovat' klavishu ScrollLock, v kachestve pereklyuchatelya s lyuboj
drugoj klavishej klaviatury.  Drugie kombinacii s klavishami-perek-
lyuchatelyami  mozhno sdelat' dopustimymi tol'ko polnost'yu  perepisav
preryvanie  klaviatury,   kotoroe   zamenilo   by preryvanie BIOS
[3.1.9].
   Imeetsya problema, svyazannaya s nekotorymi kombinaciyami s klavi-
shej Ctrl, takimi kak Ctrl + H, I, M i [, poskol'ku oni generiruyut
kody ASCII, identichnye tem, kotorye generiruyut klavishi  <BackSpa-
ce>, <Tab>, <Enter> i <Escape>.  V [3.1.8] pokazano kak programma
na assemblere mozhet mozhet, proveriv skan-kody, opredelit' byla li
nazhata upravlyayushchaya klavisha ili  kombinaciya bukvy s Ctrl (skan-kod
nahoditsya  v AH, kogda my poluchaem kod nazhatoj klavishi cherez pre-
ryvanie 16H).  K  sozhaleniyu,  programmy  na  Bejsike lisheny takoj
vozmozhnosti.  V takom sluchae programma mozhet popytat'sya razlichit'
eti dve vozmozhnosti, analiziruya sostoyanie registra statusa.  Esli
bit 2 bajta statusa po adresu  0040:0017  ustanovlen,  to klavisha
Ctrl  -  nazhata.  |tot metod rabotaet tol'ko v tot moment,  kogda
proishodit nazhatie klavishi, no  ne  togda, kogda Vy berete simvol
iz bufera klaviatury cherez nekotoroe vremya.
   Klaviatura PCjr imeet tol'ko 63 klavishi, po sravneniyu s 83 dlya
IBM PC ili XT i 84 dlya AT. Nekotorye kombinacii klavish-pereklyucha-
telej  sluzhat dlya imitacii nekotoryh nedostayushchih klavish (kombina-
cii s ispol'zovaniem funkcional'nyh klavish privedeny v [3.2.5]):

   Kombinaciya klavish PCjr      PC/XT/AT ekvivalenty

   Alt + Fn + 0-9              0-9 (skan-kody dopolnitel'noj cif-
                               rovoj klaviatury
   Alt + /                     \
   Alt + '                     `
   Alt + [                     |
   Alt + ]                     ~
   Alt + .                     * (skan-kod, kak ot klavishi PrtSc
   Shift + Del                 . (skan-kod, kak ot dop. kl-ry)


   Klaviatura PCjr dopuskaet takzhe  sleduyushchie unikal'nye kombina-
cii s uchastiem klavish-pereklyuchatelej:

   Fn + Shift + Esc            pereklyuchaet cifrovye klavishi v
                               funkcional'nye
   Ctrl + Alt + CapsLock       pereklyuchaet zvukovoe podtverzhdenie
                               nazhatiya klavishi
   Ctrl + Alt + Ins            zapuskaet diagnostiku
   Ctrl + Alt + CursorLeft     sdvigaet ekran vlevo
   Ctrl + Alt + CursorRight    sdvigaet ekran vpravo





   Za isklyucheniem klavishi Ins, vse ostal'nye klavishi-pereklyuchate-
li  ne proizvodyat koda, kotoryj pomeshchalsya by v bufer  klaviatury.
Vmesto etogo, oni izmenyayut sostoyanie dvuh bajtov statusa, kotorye
raspolozheny   v  oblasti  dannyh  BIOS  po  adresam  0040:0017  i
0040:0018.  Preryvanie klaviatury proveryaet ustanovku etih bajtov
pered  tem kak prisvoit' kod vvedennomu simvolu.  Vashi  programmy
imeyut dostup k registram statusa i mogut izmenit' ustanovku lyuboj
iz klavish-pereklyuchatelej kak ob®yasneno v [3.1.7].
   Drugie  bity registra statusa pokazyvayut nazhata li dannaya kla-
visha-pereklyuchatel' v tekushchij moment. |to svojstvo pozvolyaet prog-
ramme ispol'zovat' klavishi-pereklyuchateli v kachestve klavish  sdvi-
ga.  Vozmozhny  potencial'nye  primeneniya  etogo,  poka ne sozdano
novyh kodov klavish.  Naprimer, <ScrollLock> mozhet byt' itspol'zo-
van dlya togo, chtoby dobavit' dobavochnyj  nabor kombinacij sdvig +
funkcional'naya klaviatura.  Programma, kotoraya budet poluchat' kod
obychnoj  funkcional'noj   klavishi,   proveryat'  nazhata li klavisha
<ScrollLock>  i sootvetstvenno interpretirovat' nazhatie  klavishi.
Otmetim, chto lyubaya iz klavish  <Shift>  obrashchaet tekushchuyu ustanovku
klavishi <NumLock>.
   Klavisha  <Ins> pomeshchaet v bufer klaviatury kod  0;82,  kotoryj
Vasha programma mozhet prochitat' v  lyuboj moment.  Odnako ustanovka
dlya  <Ins>  v bajtah registra statusa menyaetsya nemedlenno.   Dazhe
esli v bufere net mesta dlya koda <Ins>, to v registre statusa pri
nazhatii  klavishi  vnosyatsya izmeneniya.  Kak <Ins>, tak i  <Scroll-
Lock>, ne vliyayut na drugie klavishi klaviatury (v otlichie ot <Num-
Lock>  i  <CapsLock>).  Vy mozhete pripisat' im lyubuyu rol',  kakuyu
zahotite.   Tehnicheskoe  rukovodstvo  IBM utverzhdaet, chto klavisha
<ScrollLock> dolzhna ispol'zovat'sya dlya pereklyucheniya mezhdu sostoya-
niyami, kogda  nazhatie  klavishi  peremeshcheniya  kursora  privodit  k
sdvizhke ekrana, a ne k peredvizheniyu kursora.
   Konechno,  Vy mozhete sozdat' vse trebuemye Vashej programme kla-
vishi-pereklyuchateli prosto  naznachiv  klavishi  dlya etoj celi. Hotya
dlya etoj celi Vy ne imeete gotovyh registrov statusa, no Vy mozhe-
te sozdat' peremennuyu, znachenie kotoroj -1 sootvetstvuet vklyuchen-
nomu sostoyaniyu Vashego pereklyuchatelya, a znachenie 0 - vyklyuchennomu.
Naprimer, ispol'zuem klavishu F10 dlya vklyucheniya i vyklyucheniya pere-
mennoj Clock:

100 '''pereklyuchenie statusa peremennoj
110 CLOCK = -1            'nachinaem s vklyuchennym sostoyaniem
120 IF X<=100 THEN NOT CLOCK 'pereklyuchaem peremennuyu





   Dlya IBM PC i  XT  dopolnitel'naya  cifrovaya klaviatura vklyuchaet
cifrovye  klavishi, klavishi <Ins> i <Del>, a takzhe klavishi + i  -.
Na AT dobavlyaetsya klavisha  "System Request" (Sys Rec), v to vremya
kak  PCjr  imeet tol'ko 4 klavishi peremeshcheniya kursora  (ostal'nye
mogut byt'  emulirovany  special'nymi  kombinaciyami  s  klavishami
<Shift>  i <Fn>, opisannymi v [3.2.2] i [3.2.5]).  Klavisha  <Num-
Lock> pereklyuchaet mezhdu ciframi  i klavishami upravleniya kursorom.
Klavishi  <Ins> i <Del> rabotayut tol'ko esli rezhim <NumLock> vklyu-
chen, t.e.  dopolnitel'naya klaviatura vydaet cifry.  Klavishi + i -
vydayut  odni  i te zhe kody nezavisimo ot ustanovki  rezhima  <Num-
Lock>.
   Cifrovye klavishi  dopolnitel'noj  klaviatury vydayut v tochnosti
te  zhe odnobajtnye kody, kotorye vydayut cifrovye klavishi verhnego
ryada osnovnoj klaviatury - t.e.   kody ASCII ot 48 do 57 dlya cifr
ot 0 do 9.  |to verno i dlya klavish + i -. Programmisty na assemb-
lere mogut opredelit' kakaya iz  dvuh  klavish  nazhata po skan-kodu
klavishi,  kotoryj nahoditsya v AH pri vozvrate kak  iz  preryvaniya
16H, tak i iz procedur vvoda odnoj klavishi preryvaniya 21H.  Otme-
tim, chto lyubaya iz klavish <Shift> perevodit klavishi dopolnitel'noj
klaviatury v rezhim protivopolozhnyj  tomu, kotoryj ustanovlen kla-
vishej <NumLock>.  Ustanovka klavishi <CapsLock> ne imeet znacheniya.
Klavisha "5" v  centre  aktivna  tol'ko  kak  cifrovaya klavisha i v
rezhime peremeshcheniya kursora vvobshche ne vydaet koda.
   Krome chetyreh obshcheprinyatyh strelok klavishi upravleniya kursorom
vklyuchayut takzhe  <Home>,  <End>,  <PgUp>  i  <PgDn>, kotorye chasto
ispol'zuyutsya  dlya  peremeshcheniya kursora srazu na celuyu stroku  ili
stranicu.  Vse oni generiruyut dvuhbajtnye  rasshirennye kody.  |ti
klavishi ne obespechivayut pryamogo kontrolya nad kursorom. Oni prosto
vydayut kody, kak i vse drugie klavishi,  i eto uzhe zadacha program-
mista preobrazovat' eti kody v peremeshcheniya kursora na ekrane.
   Dopustimy nekotorye kombinacii klavish dopolnitel'noj klaviatu-
ry s klavishej Ctrl.  <NumLock>  dolzhen sootvetstvovat' rezhimu up-
ravleniya kursorom, chtoby eti kombinacii rabotali. V [3.1.7] poka-
zano kak Vasha programma mozhet  avtomaticheski  ustanavlivat' rezhim
NumLock. Vot perechen' kodov klavish dopolnitel'noj klaviatury:

   Kody ASCII:          43                   +
                        45                   -
                        46                   .
                        48-57                0-9
   Rasshirennye kody:

   72,75,77,80          CursorUp,Left,Right&Down
   71,73,79,81          Home,PgUp,End,PgDn
   82,83                Ins,Del
   115,116              Ctlr-cursor left, -cursor right
   117,118,119,132      Ctlr-end, -PgDn, -Home, -PgUp


   AT  imeet  84-yu klavishu, Sys Req, kotoraya unikal'na  po  svoej
funkcii. Klavisha prednaznachena  dlya mnogopol'zovatel'skih sistem,
kak sposob vhoda v glavnoe menyu sistemy.  Kogda klavisha nazhimaet-
sya, v AX poyavlyaetsya kod 8500H i  vypolnyaetsya  preryvanie 15H. Pri
otpuskanii  klavishi v AX poyavlyaetsya kod 8501H, i opyat' zhe  vypol-
nyaetsya preryvanie 15H. BIOS AT  ne obrabatyvaet funkcii 84H i 85H
preryvaniya  15H,  a prosto delaet vozvrat.  No  mozhno  programmno
zamenit' vektor preryvaniya dlya 15H, chtoby on ukazyval na procedu-
ru  obrabotki  klavishi Sys Req.  Takaya procedura  dolzhna  snachala
prochitat' AL, chtoby uznat'  byla  li  klavisha nazhata (AL = 0) ili
otpushchena (AL = 1).  Zametim, chto preryvanie 15H predostavlyaet ryad
procedur, nekotorye iz  kotoryh   mogut  potrebovat'sya  programme
obrabotki  Sys  Req.  V etom sluchae procedura obrabotki  Sys  Req
dolzhna vosstanavlivat' zamenennyj  ej vektor preryvaniya, i esli v
AH ukazany funkcii otlichnye ot 84H i 85H, to nado peredat' uprav-
lenie original'nomu preryvaniyu 15H [1.2.4].





   10 funkcional'nyh klavish generiruyut razlichnye kody v sochetanii
s  Shift,  Ctrl i Alt, chto obespechivaet 40 raznyh variantov.   Vo
vseh sluchayah generiruetsya dvuhbajtnyj  rasshirennyj kod, v kotorom
pervyj bajt vsegda ASCII 0, a vtoroj bajt priveden v tablice:

   Kody                  Klavishi

   59-68                 F1-F10
   84-93                 Shift + F1-F10
   94-103                Ctrl + F1-F10
   104-113               Alt + F1-F10

Slishkom  mnogo kombinacij s ispol'zovaniem funkcional'nyh  klavish
mogut smushchat' pol'zovatelya,  no  esli  Vam  potrebovalos'  eshche 10
kombinacij, to mozhno ispol'zovat' sochetanie <ScrollLock> +  <Fn>,
kak ob®yasneno v [3.2.3].
   Klaviatura PCjr imeet tol'ko 62 klavishi, po sravneniyu s 83 dlya
IBM PC i XT, i 84 dlya AT.  Nekotorye kombinacii s uchastiem  funk-
cional'nyh klavish  emuliruyut  chast'  nedostayushchih klavish, soglasno
sleduyushchej tablice:

     PCjr kombinacii        PC/XT/AT ekvivalenty

     Fn + 1-0               F1-F10
     Fn + B                 Break
     Fn + E                 Ctrl + PrtSc
     Fn + P                 Shift + PrtSc
     Fn + Q                 Ctrl + NumLock
     Fn + S                 ScrollLock
     Fn + CursorLeft        PgUp
     Fn + CursorRight       PgDn
     Fn + CursorUp          Home
     Fn + CursorDown        End
     Fn + -                 (skan-kod serogo minusa)
     Fn + =                 (skan-kod serogo plyusa)

   Kombinacii s uchastiem klavish-pereklyuchatelej opisany v [3.2.2].





   Pod  pereprogrammirovaniem klavishi ponimaetsya sposob zastavit'
ee vydavat' drugoj kod.  No k tomu vremeni, kogda programma polu-
chaet  kod nazhatoj klavishi, preryvanie klaviatury uzhe prointerpre-
tirovalo vhodyashchij skan-kod i preobrazovalo  ego v nekotoryj zara-
nee  predopredelennyj kod ASCII ili rasshirennyj kod.  K  schast'yu,
nachinaya s MS DOS versii 2.0,  sistema soderzhit sredstva pereprog-
rammirovaniya  klavish.   |to sredstvo dejstvuet tol'ko  esli  vvod
vosprinimaetsya cherez  funkcii  DOS  vvoda  s klaviatury - funkcii
preryvaniya  BIOS  16H prodolzhayut interpretirovat' nazhatiya  klavish
normal'nym obrazom.
   Pereprogrammirovanie dostupno za schet Esc-posledovatel'nostej.
Korotkaya  stroka,  kotoraya nachinaetsya s simvola Esc  (ASCII  27),
prednaznachaetsya dlya vyvoda na  "standartnoe  ustrojstvo  vyvoda",
t.e.  na terminal.  No blagodarya nalichiyu koda Esc simvoly dazhe ne
dostigayut monitora.  Vmesto  etogo takaya stroka zastavlyaet MS DOS
po  drugomu  interpretirovat' klavishu, ukazannuyu v  etoj  stroke.
Kazhdoe izmenenie  klavishi  trebuet  sobstvennoj  stroki, pri etom
odin  i tot zhe kod mozhet prisvaivat'sya kakomu  ugodno  kolichestvu
klavish.
   Obshchij vid takoj stroki takoj: ona nachinaetsya s koda Esc (ASCII
27),  za kotorym idet [, zatem nomer koda pereopredelyaemoj klavi-
shi, zatem tochka s zapyatoj (;), zatem novyj nomer koda, prisvaiva-
emyj   klavishe  i,  nakonec,  simvol p.   Takim  obrazom,  stroka
27,'[65;97p' menyaet A  (ASCII  65)  na  a (ASCII 97). Rasshirennye
kody  zapisyvayutsya  s  ukazaniem oboih bajtov, prichem  za  pervym
nulevym   bajtom   dolzhny   stoyat'   tochka   s   zapyatoj.  Stroka
27,'[0;68;0;83p' prisvaivaet klavishe F10 (0;68) tot zhe kod, chto i
klavishe Delete (0;83). Vy  mozhete  prisvaivat' tol'ko rasshirennye
kody, privedennye v tablice rasshirennyh kodov [3.3.5].
   Imeetsya  neskol'ko variantov dopustimogo vida stroki.  Vo-per-
vyh, simvol'nye klavishi mogut oboznachat'sya samim simvolom, zaklyu-
chennym  v  kavychki.  Takim obrazom, stroka  27,'["A";"a"p'  takzhe
menyaet A na a. Vo-vtoryh klavishe mozhet byt' prisvoena celaya stro-
ka  simvolov,  putem ukazaniya simvolov ili ih kodovyh  nomerov  v
vyrazhenii. Stroka  27,'["A";"A  is  for Apple"p' privedet k tomu,
chto pri nazhatii na klavishu A v verhnem registre, budet pechatat'sya
vsya strochka A is for Apple. Na  samom dele eti Esc-posledovatel'-
nosti - nichego bolee, chem stroki, v kotoryh pervyj kod ili simvol
ukazyvaet kakuyu klavishu nuzhno  pereopredelit', a ostavshayasya chast'
stroki  ukazyvaet kakoe znachenie Vy hotite ej pridat'.   Pomnite,
chto nomera kodov dolzhny byt' vsegda razdeleny tochkoj s zapyatoj, a
simvoly zaklyucheny v kavychki. Kody i simvoly mogut byt' peremeshany
v lyubyh sochetaniyah.  Dlya togo  chtoby takie pereopredeleniya klavish
byli vozmozhny, neobhodimo chtoby drajver ANSI.SYS byl zagruzhen pri
zagruzke operacionnoj sistemy. V  protivnom sluchae Esc-posledova-
tel'nosti budut ignorirovat'sya.  V prilozhenii D pokazano kak  eto
delaetsya.
   Nekotorye aspekty  funkcionirovaniya klaviatury programmiruyutsya
na PCjr i AT. Procedury dostupnye dlya AT interesny v osnovnom dlya
sistemnyh  programmistov;  poskol'ku  oni nuzhny ves'ma nemnogim i
dostatochno  slozhny, to my ne budem rassmatrivat' ih  zdes'.   Pri
neobhodimosti Vam pridetsya  obratit'sya k Tehnicheskomu rukovodstvu


po AT. V sluchae PCjr preryvanie BIOS 16H imeet dve dopolnitel'nye
funkcii (AH = 3 i AH = 4), pervaya iz kotoryh ustanavlivaet chasto-
tu avtopovtora. "CHastota avtopovtora" - eto ta chastota, s kotoroj
klavisha posylaet svoj kod, kogda  ona postoyanno derzhitsya nazhatoj.
Vtoraya  funkciya vklyuchaet i vyklyuchaet zvukovoe podtverzhdenie nazha-
tiya klavishi. Dlya funkcii 3 nado pomestit' v AL 0, chtoby vernut'sya
k  chastote avtopovtora, ustanavlivaemoj po umolchaniyu,  1 -  chtoby
uvelichit'  nachal'nuyu  zaderzhku  pered  tem,  kak nachinaetsya rezhim
avtopovtora,  2 - chtoby umen'shit' chastotu avtopovtora vdvoe, 3  -
chtoby ustanovit' svojstva 1 i 2 vmeste i 4 - vyklyuchit' avtopovtor
voobshche.  Dlya funkcii 4, pomestiv v AL 1, Vy budete imet' zvukovoe
podtverzhdenie nazhatiya klavishi, a 0 - vyklyuchite ego.

   Vysokij uroven'.

   K neschast'yu, operatory  Bejsika  PRINT  i  WRITE ne rabotayut s
Esc-posledovatel'nostyami.   Programmy na Bejsike dolzhny  vklyuchat'
prostye assemblernye podprogrammy, ispol'zuyushchie preryvaniya vyvoda
MS DOS, obsuzhdaemye nizhe v chasti "Srednij uroven'".  V prilozhenii
G pokazano, kak vklyuchit'  assemblernye  procedury  v programmy na
Bejsike.   V  privedennom primere predpolagaetsya,  chto  procedura
nahoditsya v pamyati, nachinaya s  adresa  2000:0000.  Operatory DATA
soderzhat assemblernyj kod. V konce stroki pereopredeleniya klavishi
dolzhen byt' dobavlen kod $.

100 DATA &H55, &H8B, &HEC, &H8B, &H5E, &H06, &H8B, &H57
110 DATA &H01, &HB4, &H09, &HCD, &H21, &H5D, &HCA, &H02, &H00
120 'pomeshchaem proceduru v pamyat' po adresu 2000:0000
130 DEF SEG = &H2000         'opredelyaem segment
140 FOR N=0 TO 16            'procedura dlinoj 17 bajt
150 READ Q                   'chitaem bajt
160 POKE N,Q                 'pomeshchaem ego v pamyat'
170 NEXT                     '
180 ''' menyaem A na a
190 Q$ = CHR$(27)+"[65;97p$" 'stroka pereopredeleniya
200 ROUTINE = 0              'ukazyvaem na stroku
210 CALL ROUTINE(Q$)         'vyzyvaem proceduru

   Srednij uroven'.

   Ispol'zujte funkciyu  9  preryvaniya  21H  dlya posylki stroki na
standartnoe  ustrojstvo vyvoda.  DS:DX dolzhny ukazyvat' na pervyj
simvol stroki v pamyati  i  stroka  dolzhna  zavershat'sya simvolom $
(24H).  Zdes' F2 (0;60) pereopredelyaetsya takim obrazom, chtoby ona
dejstvovala kak Del (0;83).

;---v segmente dannyh
CHANGE_KEY   DB   27,'[0;60;0;83p$'

;---dlya izmeneniya opredeleniya klavishi
   LEA  DX,CHANGE_KEY       ;DS:DX dolzhny ukazyvat' na stroku
   MOV  AH,9                ;nomer funkcii
   INT  21H                 ;pereopredelenie klavishi





   Makroopredelenie - eto stroka  simvolov,  kotoraya  budet vyvo-
dit'sya  pri  nazhatii odnoj klavishi.  Makroopredeleniya mogut  byt'
zaprogrammirovany v  interpretatore  Bejsika ili na urovne opera-
cionnoj sistemy dlya umen'sheniya pechataniya.  Poskol'ku stroka mozhet
soderzhat' upravlyayushchie  kody,  takie  kak  simvol vozvrata karetki
(ASCII  13), to odno makroopredelenie mozhet vypolnyat' celyj nabor
komand.  Dlya uskoreniya razrabotki programm, naprimer, mozhno napi-
sat'  makroopredelenie, soderzhashchee vse neobhodimye komandy, chtoby
ottranslirovat' i skomponovat' opredelennuyu programmu.
   Makroopredeleniya,   obespechivaemye   Bejsikom,  rabotayut kak v
Bejsikovskih programmah, tak i na komandnom urovne Bejsika.  Nap-
rimer, esli Vy  zaprogrammirovali  klavishu,  chtoby pri ee nazhatii
vyvodilos' slovo "Orangutan", to pri nazhatii etoj klavishi funkciya
INPUT poluchit vsyu etu stroku, a cikl, vklyuchayushchij INKEY$, posledo-
vatel'no poluchit devyat' simvolov.  S drugoj storony, makrooprede-
leniya, sozdannye na urovne  operacionnoj sistemy, vsegda rabotayut
na  komandnom  urovne DOS, no vnutri programm oni budut  rabotat'
tol'ko esli programma dlya vvoda  s  klaviatury ispol'zuet funkcii
DOS.   Poskol'ku bol'shinstvo kommercheskih  programmnyh  produktov
ispol'zuyut preryvanie BIOS 16H, to dlya etih programm makrooprede-
leniya ne budut rabotat'.  Konechno, sredstva dlya sozdaniya makroop-
redelenij mogut byt' vstavleny  v  procedury  vvoda s klaviatury.
Naprimer, chtoby pozvolit' pol'zovatelyu programmy sozdat' makroop-
redelenie dlya F1, zaprosiv  stroku  i pomestiv ee v MACRO1$, nado
na Bejsike napisat' chto-to vrode:

1000 '''procedura vvoda rasshirennogo koda, v C - 2-j bajt koda
1010 IF C=59 THEN LOCATE X,Y: PRINT MACRO1$

   Vysokij uroven'.

   Bejsik imeet vstroennyj mehanizm sozdaniya makroopredelenij, no
on  pozvolyaet programmirovat' tol'ko 10 funkcional'nyh klavish,  a
stroki dolzhny byt' ne dlinnee 15  simvolov.  Bejsik rassmatrivaet
funkcional'nye klavishi, kak programmiruemye klavishi. Operator KEY
prisvaivaet makroopredelenie  dannoj  klavishe. Stroka KEY 5,"END"
privodit  k  tomu, chto funkcional'naya klavisha #5  budet  posylat'
slovo END v tekushchuyu poziciyu kursora na ekrane.
   Simvoly  sostavlyayushchie stroku mogut vvodit'sya kak stroki simvo-
lov, kak ASCII kody (ispol'zuya  CHR$)  ili  kak kombinaciya togo i
drugogo.   Komandy KEY 5,"A" i KEY 5,CHR$(65) ekvivalentny.   Dlya
togo, chtoby stroka srazu ispolnyalas' nado dobavit' v konce stroki
simvol  vozvrata  karetki (ASCII 13).  Komanda  FILES,  vyvodyashchaya
katalog diska, ispolnyaetsya posle  togo, kak Vy prisvoite eto zna-
chenie F1 komandoj KEY 1,"FILES"+CHR$(13).
   Bejsik  prisvaivaet desyati funkcional'nym klavisham rasprostra-
nennye operatory Bejsika. Vy mozhete otmenit' makroopredelenie dlya
dannoj  klavishi, prisvoiv ej pustuyu stroku,naprimer, komanda  KEY
1,"" privedet k tomu, chto  pri  nazhatii  F1  nichego  vvodit'sya ne
budet. Pervye shest' simvolov kazhdoj stroki avtomaticheski vyvodyat-
sya v nizhnej chasti ekrana  interpretatorom  Bejsika. Vy mozhete up-
ravlyat' nalichiem etogo vyvoda ispol'zuya komandy KEY ON i KEY OFF.
Dlya togo chtoby vyvesti na ekran polnye opredeleniya klavish, vvedi-
te komandu KEY LIST. Vot neskol'ko primerov:


KEY 1,"ERASE"           ; teper' F1 vyvodit "ERASE"
KEY 10,"LIST"+CHR$(13)  ; teper' F10 vydaet listing
KEY 7,""                ; teper' F7 nichego ne vydaet
KEY OFF                 ; podavlyaet vyvod vnizu ekrana
KEY ON                  ; vklyuchaet vyvod vnizu ekrana
KEY LIST                ; vydaet spisok znachenij 10 klavish

Dlya  sozdaniya makroopredelenij drugih klavish v Bejsike, Vy dolzhny
ispol'zovat' sredstva MS DOS, opisannye v [3.2.6].
   Srednij uroven'.

   V MS DOS makroopredeleniya sozdayutsya s pomoshch'yu metoda pereprog-
rammirovaniya klavish, opisannogo v [3.2.6]. Edinstvennoe otlichie v
tom, chto  klavishe  sopostavlyaetsya  celaya  stroka simvolov. Stroka
mozhet  byt' vvedena v vide simvolov, zaklyuchennyh v kavychki, ili v
vide kodov ili kombinacii togo i drugogo. Vot neskol'ko primerov:

27,'["A";"SET"p'          ; prisvaivaet SET zaglavnoj A
27,'["ASET"p'             ; ekvivalentno predydushchemu
27,'[27;"dir";13p'        ; prisvaivaet dir<CR> klavishe Esc
27,'[0;59;"copy *.* b:";13p'  ;prisvaivaet F1 komandu
27,'[0;68;0;72;0;72;0;72p'    ;zastavlyaet F10 sdvinut' kursor na
                              ;tri stroki vverh





   Kogda vvoditsya kombinaciya Ctrl-Break, to preryvanie klaviatury
ustanavlivaet flag, ukazyvayushchij chto dolzhna byt' vypolnena  proce-
dura obrabotki Ctrl-Break.  Upravlenie  peredaetsya etoj procedure
tol'ko v tot  moment,  kogda  programma  ispol'zuet  funkciyu DOS,
sposobnuyu raspoznavat' etot flag. Obychno tol'ko standartnye funk-
cii vvoda/vyvoda MS DOS mogut  raspoznavat' etot flag (funkcii ot
1 do C preryvaniya 21H, za isklyucheniem funkcij 6 i 7). No pomestiv
stroku BREAK=ON libo  v  fajl  AUTOEXEC.BAT,  libo  v CONFIG.SYS,
ispol'zuemye  MS  DOS pri starte sistemy, Vy  poluchite  situaciyu,
kogda obrashchenie k lyuboj funkcii  DOS  privedet k vyzovu procedury
obrabotki Ctrl-Break. Pri etom vypolnenie programmy budet nemnogo
zamedleno.
   Procedura  obrabotki  Ctrl-Break  daet  vozmozhnost'  zavershit'
programmu  v lyuboj moment vremeni.  Kogda funkciya DOS  raspoznaet
status Ctrl-Break, to upravlenie peredaetsya procedure, na kotoruyu
ukazyvaet vektor preryvaniya 23H. DOS ispol'zuet etu proceduru dlya
zaversheniya rabotayushchej programmy.  No procedura mozhet byt' perepi-
sana Vami, s tem chtoby ona udovletvoryala lyubym Vashim trebovaniyam.
|ta procedura  dolzhna  byt'  programmiruemoj,  s  tem chtoby pered
zaversheniem programmy mogli byt' vypolneny vse kriticheskie opera-
cii. Mozhet trebovat'sya  vyravnivanie steka, s tem chtoby SP ukazy-
val  na  vtoroe slovo ot vershiny (pervoe slovo dlya programm  COM)
pered vypolneniem zavershayushchej instrukcii RET. Vektora preryvaniya,
izmenennye  programmoj dolzhny byt' vosstanovleny, a vse  otkrytye
ustrojstva vvoda/vyvoda -  zakryty.  Esli byli zapreshcheny preryva-
niya, to nado razreshit' ih.  Vse eto dolzhno obespechit' mashine voz-
mozhnost' normal'no rabotat' so sleduyushchej  programmoj posle zaver-
sheniya  programmy  po Ctrl-Break.  Drugaya  al'ternativa -  sdelat'
proceduru  obrabotki  Ctrl-Break,  sostoyashchej  iz odnoj instrukcii
IRET, chto zapreshchaet zavershenie programmy takim sposobom.

   Srednij uroven'.

   V  dannom primere vyhod iz programmy proishodit posle vyravni-
vaniya steka.   Procedura  konchaetsya  instrukciej  RET, a ne IRET,
poskol'ku v dannom sluchae ona dejstvuet v tochnosti tak zhe, kak  i
instrukciya RET pri normal'nom  zavershenii  programmy.   V moment,
kogda ona ispol'zuetsya, ukazatel' steka (SP) dolzhen ukazyvat'  na
vtoroe slovo steka. |to  predpolagaet, chto programma v forme EXE.
Pomnite,  chto  stek pomeshchaaet svoe pervoe slovo v  samuyu  starshuyu
yachejku pamyati, vtoroe - v yachejku  nizhe, i t.d.  Esli razmer steka
400  bajt,  to nado ustanovit' SP na 396.  Dlya programm COM  nado
ustanavlivat' ukazatel' steka  na  pervoe  slovo steka ili prosto
zavershat' proceduru obrabotki Ctrl-Break preryvaniem 21H.

;---eto novaya procedura obrabotki Ctrl-Break
C_B     PROC FAR
        MOV  AX,396           ;znachenie dlya vtorogo slova steka
        MOV  SP,AX            ;vyravnivaem ukazatel' steka
        RET                   ;vozvrat v DOS
C_B     ENDP                  ;


;---izmenenie vektora preryvaniya
        PUSH DS               ;sohranyaem registr
        MOV  AX,SEG C_B       ;gotovim adres procedury
        MOV  DS,AX            ;
        MOV  DX,OFFSET C_B    ;
        MOV  AH,25H           ;nomer funkcii
        MOV  AL,23H           ;nomer vektora
        INT  21H              ;izmenyaem vektor
        POP  DS               ;vosstanavlivaem registr

   Programma  mozhet v lyuboe vremya proverit' byl li sdelan  zapros
na vypolnenie procedury obrabotki Ctrl-Break. Nado pomestit' v AL
0  i  vyzvat' funkciyu 33 preryvaniya 21H.  Pri vozvrate  DL  budet
soderzhat' 1, esli byl ustanovlen flag preryvaniya po Ctrl-Break, i
0  -  v protivnom sluchae.  Esli pri vyzove pomestit' v AL  1,  to
status budet ustanovlen.  V etom  sluchae,  pered vyzovom funkcii,
pomestite v DL 0 ili 1, chtoby flag byl ustanovlen ili ochishchen.





   Klavisha  PrtSc  vydaet zvezdochku (ASCII 42),  esli  nazhat'  ee
odnu, ona vydaet  rasshirennyj  kod  114,  esli nazhat' ee vmeste s
klavishej  Ctrl.  No kombinaciya <Shift> + <PrtSc> imeet sovershenno
otdel'nyj status. Nazhatie na drugie klavishi zastavlyayut preryvanie
klaviatury  pomeshchat'  ih kody v bufer klaviatury (ili,  dlya  kla-
vish-pereklyuchatelej,  zapisyvat'  ih  sostoyanie  [3.1.7]). Nazhatie
klavishi ne vliyaet na vypolnyaemuyu programmu, do teh por poka prog-
ramma ne stanet schityvat' simvol klavishi iz bufera klaviatury. No
kombinaciya  <Shift>  + <PrtSc> zastavlyaet  preryvanie  klaviatury
nemedlenno peredat'  upravlenie  procedure,  na kotoruyu ukazyvaet
vektor preryvaniya 5.  V nekot'orom smysle ona rabotaet kak  appa-
ratnoe preryvanie.
   Preryvanie  5  zaprogrammirovano  takim  obrazom, chtoby vydat'
soderzhimoe  ekrana na printer.  No vektor preryvaniya mozhet ukazy-
vat' na proceduru,  prednaznachennuyu  dlya  sovershenno drugoj celi.
Naprimer,  izoshchrennaya programma imitacii, kotoroj trebuyutsya  chasy
dlya zaversheniya svoej raboty, mozhet  prervana v lyuboe vremya kombi-
naciej Shift + PrtSc, chtoby ona vydala raport o tekushchem sostoyanii
raschetov. Vam mozhet takzhe zahotet'sya, chtoby na printer mozhno bylo
posylat' kopiyu graficheskogo ekrana. Drugaya vozmozhnost', ispol'zo-
vat' PrtSc kak  sposob  dostupa  k  programme,  kotoraya nahoditsya
rezidentno v pamyati vo vremya zagruzki MS DOS [1.3.4]. Takaya stra-
tegiya pozvolit Vam  napisat'  utilitu,  kotoraya mozhet rabotat' iz
drugogo programmnogo obespecheniya.
   Nizkij uroven'.
   Zdes' privedena osnovnaya forma pereprogrammirovaniya procedury.
Ne   zabud'te   vosstanovit'   original'nyj   vektor   preryvaniya
(F000:FF54)  pri zavershenii programmy.  Esli Vy zabudete  sdelat'
eto, to vse budet idti normal'no, do teh por poka ne budet nazhata
kombinaciya Shift + PrtSc, a togda proizojdet krah sistemy  (bolee
polnyj primer programmirovaniya preryvaniya sm. v [1.2.3]).

;---izmenit' vektor preryvaniya dlya PrtSc
   CLI                       ;zapret preryvanij
   MOV  AX,SEG NEW_ROUTINE   ;poluchaem adres procedury
   MOV  DS,AX                ;
   MOV  DX,OFFSET NEW_ROUTINE   ;
   MOV  AL,5                 ;nomer izmenyaemogo vektora
   MOV  AH,25H               ;nomer funkcii
   INT  21H                  ;izmenyaem vektor
   STI                       ;razreshaem preryvaniya
    .
    .
;---opisanie procedury PrtSc
NEW_ROUTINE  PROC FAR
             STI             ;razreshaem preryvaniya
             PUSH AX         ;sohranyaem registry
              .
              .
             MOV  CX,100     ;Vasha procedura
              .
              .
             POP  AX         ;vosstanavlivaem registry
             IRET            ;vozvrat iz preryvaniya
NEW_ROUTINE  ENDP            ;




   Razlichnye  kody klavish i kody simvolov mogut privodit' k nedo-
razumeniyam. V nizheprivedennyh tablicah vse oni perechisleny. Obra-
tite vnimanie na sleduyushchie anomalii:

   - klavisha Ins yavlyaetsya edinstvennoj, kotoraya pri nazhatii,  kak
vydaet kod simvola v  bufer  klaviatury,  tak i menyaet status re-
gistra klavish-pereklyuchatelej.

   -  imeetsya  4  koda ASCII, kotorye mogut byt'  polucheny  dvumya
sposobami. ASCII 8 - nazhatiem klavishi BackSpace i Ctrl-H, ASCII 9
-  klavishi  Tab i Ctrl-I, ASCII 13 - klavishi  Enter i  Ctrl-M,  a
ASCII 27 - klavishi Esc i Ctrl-[.

   - simvoly, sootvetstvuyushchie 32 upravlyayushchim kodam ASCII ne vyvo-
dyatsya  na  ekran, pri ispol'zovanii funkcij  vvoda s  klaviatury,
obespechivayushchih avtomaticheskoe eho. Oni mogut byt' vyvedeny libo s
pomoshch'yu  funkcii 10H preryvaniya 10H, libo pryamym vyvodom v pamyat'
displeya (oba sposoba obsuzhdayutsya v [4.3.1]).

   - kombinacii klavishi Ctrl s bukvami  alfavita generiruyut odno-
bajtnye  kody  ASCII.  Vse ostal'nye kombinacii  Ctrl  generiruyut
dvuhbajtnye (rasshirennye) kody.

   - klavisha <5>  dopolnitel'noj  klaviatury  ne  dejstvuet, esli
ustanovlen rezhim upravleniya kursorom klavishej NumLock.

   -  kombinacii Shift-PrtSc i Ctrl-Alt (a takzhe SysReq  dlya  AT)
eto edinstvennye sluchai, kogda  kombinaciya  klavish privodit k ne-
medlennomu  vyzovu nekotoroj procedury.  Iz nih tol'ko pervaya pe-
reprogrammiruema.  Preryvanie  obrabotki Ctrl-Break (takzhe perep-
rogrammiruemoe)  vyzyvaetsya tol'ko togda, kogda status Ctrl-Break
budet obnaruzhen proceduroj MS DOS.

   - lyuboj kod ASCII, krome 0,  mozhet  byt'  vveden putem nazhatiya
klavishi  Alt, nabora koda ASCII na dopolnitel'noj  klaviature  i,
zatem, otpuskaniya klavishi Alt.  Poskol'ku kod 0 isklyuchen, to ras-
shirennye kody ne mogut byt' vvedeny takim sposobom.

Otmetim, chto Vy prakticheski nichego ne mozhete sdelat', chtoby preo-
dolet'  ogranicheniya,  nakladyvaemye   na  nedopustimye kombinacii
klavish.  Naprimer, Vy ne mozhete opredelit' kombinaciyu Ctrl + Cur-
sorUp, prinimaya kod CursorUp,  a  zatem  proveryaya registr statusa
perklyuchatelej  dlya opredeleniya togo, byla li nazhata klavisha Ctrl.
Esli Ctrl byla nazhata, to klavisha CursorUp voobshche ne vydaet nika-
kogo koda.





   Imeetsya  ryad  soglashenij  otnositel'no  ispol'zovaniya  klavish,
kotorye dolzhny vypolnyat'sya vsemi programmami.  Oni opisany v Teh-
nicheskom rukovodstve i esli programmisty budut priderzhivat'sya ih,
to pol'zovatelyu budet legko perehodit'  ot odnoj programmy k dru-
goj. Zametim, odnako, chto programmnoe obespechenie samoj firmy IBM
ne vsegda sleduet etim soglasheniyam. Oni takovy:

   ScrollLock        Pereklyuchaet rezhim vyvoda na terminal, pri
                     kotorom peremeshchenie kursora sdvigaet ekran,
                     a ne sam kursor
   CTRL 4/6          Sdvigaet kursor na slovo vlevo/vpravo.
                     Drugaya vozmozhnost': gorizontal'nyj sdvig
                     ekrana na poziciyu tabulyacii vlevo/vpravo.
   Pg Up             Vozvrat na 25 strok nazad.
   Pg Dn             Sdvig na 25 strok vpered.
   CTRL END          Udalenie teksta ot pozicii kursora do konca
                     stroki.
   CTRL PgDn         Udalenie teksta ot pozicii kursora do konca
                     ekrana.
   HOME              V tekste peremeshchaet kursor k nachalu stroki
                     ili dokumenta. V menyu - vozvrashchaet v glavnoe
                     menyu.
   CTRL HOME         CHistit ekran i pomeshchaet kursor v levyj
                     verhnij ugol.
   END               Peremeshchaet kursor k koncu stroki ili k
                     koncu dokumenta.
   BACKSPACE/DELETE  DELETE unichtozhaet simvol, na kotoryj ukazy-
                     vaet kursor, i sdvigaet ostatok stroki na
                     odnu poziciyu vlevo. BACKSPACE udalyaet simvol
                     sleva ot kursora i delaet to zhe samoe.
   INS               Pereklyuchaet rezhim vstavki/zameny.
   TAB/BACKTAB       Peremeshchaet kursor v sleduyushchuyu poziciyu tabu-
                     lyacii, vpravo - esli byla nazhata odna i
                     vlevo - esli vmeste s klavishej Shift.
   ESC               Vyhod iz programmy ili procedury.





   Kazhdaya klavisha generiruet dva tipa skan-kodov, "kod nazhatiya" -
kogda klavisha nazhimaetsya,  i  "kod  osvobozhdeniya" - kogda klavisha
otpuskaetsya.   Dlya vseh mashin, krome AT, kod osvobozhdeniya na  128
bol'she koda nazhatiya (bit 7 = 1).  Takim obrazom klavisha T sozdaet
kod 20 pri nazhatii i kod 148 pri otpuskanii. AT ispol'zuet odnu i
tu zhe cepochku bitov dlya  kodov  nazhatiya  i  osvobozhdeniya, no kody
osvobozhdeniya  sostoyat  iz dvuh bajtov, pervyj iz  kotoryh  vsegda
raven 0F0H. PCjr imeet special'nyj skan-kod mnimoj klavishi, nomer
55.  |tot kod porozhdaetsya, kogda byli odnovremenno nazhaty tri ili
bolee klavish, chto pomogaet izbezhat' oshibok pri vvode.  Preryvanie
klaviatury  otbrasyvaet etot kod i on ne svyazyvaetsya  ni s  kakim
kodom ASCII ili rasshirennym kodom.

                      Klavishi pishushchej mashinki

   Klavisha Kod nazhatiya  Klavisha Kod nazhatiya  Klavisha Kod nazhatiya

     "1"       2          "T"        20        "L"       38
     "2"       3          "Y"        21        ";"       39
     "3"       4          "U"        22        "'"       40
     "4"       5          "I"        23        "`"       41
     "5"       6          "O"        24        "\"       43
     "6"       7          "P"        25        "Z"       44
     "7"       8          "["        26        "X"       45
     "8"       9          "]"        27        "C"       46
     "9"       10         "A"        30        "V"       47
     "0"       11         "S"        31        "B"       48
     "-"       12         "D"        32        "N"       49
     "="       13         "F"        33        "M"       50
     "Q"       16         "G"        34        ","       51
     "W"       17         "H"        35        "."       52
     "E"       18         "J"        36        "/"       53
     "R"       19         "K"        37      probel      57

                        Upravlyayushchie klavishi

   Esc - 1               Ctrl - 29           Alt - 56
   BackSpace - 14        left shift - 42     CapsLock - 58
   Tab - 15              right shift - 42    NumLock - 58
   Enter - 28            PrtSc - 55          ScrollLock - 70

                       Funkcional'nye klavishi

   F1 - 59               F5 - 63             F9 - 67
   F2 - 60               F6 - 64             F10 - 68
   F3 - 61               F7 - 65
   F4 - 62               F8 - 66

                 Klavishi dopolnitel'noj klaviatury

   "7" - 71           "5" - 76            "3" - 81
   "8" - 72           "6" - 77            "0" - 82
   "9" - 73           "+" - 78            "." - 83
   "-" - 74           "1" - 79      Sys Req - 132 (tol'ko AT)
   "4" - 75           "2" - 80       mnimaya - 55 (tol'ko PCjr)




   Nomera  kodov  ot 0 do 31, upravlyayushchih kodov, ob®yasneny  bolee
detal'no v [7.1.9].  Napominaem,  chto lyuboj kod ASCII ot 1 do 255
mozhet  byt' vveden s klaviatury, esli derzhat' nazhatoj klavishu Alt
pri nabore nomera koda na dopolnitel'noj klaviature (s sootvetst-
venno  ustanovlennym  rezhimom NumLock).  Kogda klavisha Alt  zatem
osvobozhdaetsya, to kod vvoditsya.
Simvol  10-nyj  16-richnyj  dvoichnyj  Simvol  10-nyj  16-richnyj  dvoichnyj

(null)     0        00     00000000     0      48       30      00110000
           1        01     00000001     1      49       31      00110001
           2        02     00000010     2      50       32      00110010
           3        03     00000011     3      51       33      00110011
           4        04     00000100     4      52       34      00110100
           5        05     00000101     5      53       35      00110101
           6        06     00000110     6      54       36      00110110
           7        07     00000111     7      55       37      00110111
           8        08     00001000     8      56       38      00111000
           9        09     00001001     9      57       39      00111001
          10        0A     00001010     :      58       3A      00111010
          11        0B     00001011     ;      59       3B      00111011
          12        0C     00001100     <      60       3C      00111100
          13        0D     00001101     =      61       3D      00111101
          14        0E     00001110     >      62       3E      00111110
          15        0F     00001111     ?      63       3F      00111111
          16        10     00010000     @      64       40      01000000
          17        11     00010001     A      65       41      01000001
          18        12     00010010     B      66       42      01000010
          19        13     00010011     C      67       43      01000011
          20        14     00010100     D      68       44      01000100
          21        15     00010101     E      69       45      01000101
          22        16     00010110     F      70       46      01000110
          23        17     00010111     G      71       47      01000111
          24        18     00011000     H      72       48      01001000
          25        19     00011001     I      73       49      01001001
          26        1A     00011010     J      74       4A      01001010
          27        1B     00011011     K      75       4B      01001011
          28        1C     00011100     L      76       4C      01001100
          29        1D     00011101     M      77       4D      01001101
          30        1E     00011110     N      78       4E      01001110
          31        1F     00011111     O      79       4F      01001111
probel    32        20     00100000     P      80       50      01010000
  !       33        21     00100001     Q      81       51      01010001
  "       34        22     00100010     R      82       52      01010010
  #       35        23     00100011     S      83       53      01010011
  $       36        24     00100100     T      84       54      01010100
  %       37        25     00100101     U      85       55      01010101
  &       38        26     00100110     V      86       56      01010110
  '       39        27     00100111     W      87       57      01010111
  (       40        28     00101000     X      88       58      01011000
  )       41        29     00101001     Y      89       59      01011001
  *       42        2A     00101010     Z      90       5A      01011010
  +       43        2B     00101011     [      91       5B      01011011
  ,       44        2C     00101100     \      92       5C      01011100
  -       45        2D     00101101     ]      93       5D      01011101
  .       46        2E     00101110     ^      94       5E      01011110
  /       47        2F     00101111     _      95       5F      01011111


Simvol  10-nyj  16-richnyj  dvoichnyj  Simvol  10-nyj  16-richnyj  dvoichnyj

  `       96        60     01100000     SHCH     153       99      10011001
  a       97        61     01100001     ¬     154       9A      10011010
  b       98        62     01100010     Y     155       9B      10011011
  c       99        63     01100011     X     156       9C      10011100
  d      100        64     01100100     |     157       9D      10011101
  e      101        65     01100101     YU     158       9E      10011110
  f      102        66     01100110     YA     159       9F      10011111
  g      103        67     01100111     a     160       A0      10100000
  h      104        68     01101000     b     161       A1      10100001
  i      105        69     01101001     v     162       A2      10100010
  j      106        6A     01101010     g     163       A3      10100011
  k      107        6B     01101011     d     164       A4      10100100
  l      108        6C     01101100     e     165       A5      10100101
  m      109        6D     01101101     zh     166       A6      10100110
  n      110        6E     01101110     z     167       A7      10100111
  o      111        6F     01101111     i     168       A8      10101000
  p      112        70     01110000     j     169       A9      10101001
  q      113        71     01110001     k     170       AA      10101010
  r      114        72     01110010     l     171       AB      10101011
  s      115        73     01110011     m     172       AC      10101100
  t      116        74     01110100     n     173       AD      10101101
  u      117        75     01110101     o     174       AE      10101110
  v      118        76     01110110     p     175       AF      10101111
  w      119        77     01110111     °     176       B0      10110000
  x      120        78     01111000     ±     177       B1      10110001
  y      121        79     01111001     ˛     178       B2      10110010
  z      122        7A     01111010     ł     179       B3      10110011
  {      123        7B     01111011     ´     180       B4      10110100
  |      124        7C     01111100     µ     181       B5      10110101
  }      125        7D     01111101     ¶     182       B6      10110110
  ~      126        7E     01111110     ·     183       B7      10110111
         127        7F     01111111     ¸     184       B8      10111000
  A      128        80     10000000     ą     185       B9      10111001
  B      129        81     10000001     ş     186       BA      10111010
  V      130        82     10000010     »     187       BB      10111011
  G      131        83     10000011     Ľ     188       BC      10111100
  D      132        84     10000100     ˝     189       BD      10111101
  E      133        85     10000101     ľ     190       BE      10111110
  ZH      134        86     10000110     ż     191       BF      10111111
  Z      135        87     10000111     A     192       C0      11000000
  I      136        88     10001000     B     193       C1      11000001
  J      137        89     10001001     V     194       C2      11000010
  K      138        8A     10001010     G     195       C3      11000011
  L      139        8B     10001011     D     196       C4      11000100
  M      140        8C     10001100     E     197       C5      11000101
  N      141        8D     10001101     ZH     198       C6      11000110
  O      142        8E     10001110     Z     199       C7      11000111
  P      143        8F     10001111     I     200       C8      11001000
  R      144        90     10010000     J     201       C9      11001001
  S      145        91     10010001     K     202       CA      11001010
  T      146        92     10010010     L     203       CB      11001011
  U      147        93     10010011     M     204       CC      11001100
  F      148        94     10010100     N     205       CD      11001101
  H      149        95     10010101     O     206       CE      11001110
  C      150        96     10010110     P     207       CF      11001111
  CH      151        97     10010111     R     208       D0      11010000
  SH      152        98     10011000     S     209       D1      11010001


Simvol  10-nyj  16-richnyj  dvoichnyj  Simvol  10-nyj  16-richnyj  dvoichnyj

  T      210        D2     11010010     shch     233       E9      11101001
  U      211        D3     11010011     ®     234       EA      11101010
  F      212        D4     11010100     y     235       EB      11101011
  H      213        D5     11010101     '     236       EC      11101100
  C      214        D6     11010110     e     237       ED      11101101
  CH      215        D7     11010111     yu     238       EE      11101110
  SH      216        D8     11011000     ya     239       EF      11101111
  SHCH      217        D9     11011001     ¨     240       F0      11110000
  ¬      218        DA     11011010     ¸     241       F1      11110001
  Y      219        DB     11011011     t     242       F2      11110010
  X      220        DC     11011100     u     243       F3      11110011
  |      221        DD     11011101     f     244       F4      11110100
  YU      222        DE     11011110     h     245       F5      11110101
  YA      223        DF     11011111     c     246       F6      11110110
  r      224        E0     11100000     ch     247       F7      11110111
  s      225        E1     11100001     sh     248       F8      11111000
  t      226        E2     11100010     shch     249       F9      11111001
  u      227        E3     11100011     ®     250       FA      11111010
  f      228        E4     11100100     y     251       FB      11111011
  h      229        E5     11100101     '     252       FC      11111100
  c      230        E6     11100110     e     253       FD      11111101
  ch      231        E7     11100111     yu     254       FE      11111110
  sh      232        E8     11101000           255       FF      11111111





   Nizhe  privedeny dlya udobstva nomerov kodov ASCII, dlya simvolov
psevdografiki, ispol'zuemyh pri postroenii linij i ramok.

  218       194      191           213      209      184
   ¬         V        ż             H        S        ¸

    195       197      180           198      216      181
   G         E        ´      ł      ZH        SH        µ

                            179
   A         B        SHCH             F        P        ľ
  192       193      217           212      207      190

             D  196                          N  205

  214       210      183           201      203      187
   C         T        ·             J        L        »

    199       215      182           204      206      185
   Z         CH        ¶      ş      M        O        ą

                            186
   U         R        ˝             I        K        Ľ
  211       208      189           200      202      188





Znachenie 2-go bajta     Sootvetstvuyushchie klavishi

   15                   Shift + Tab ("back-tab")
   16-25                Alt-Q - Alt-P (verhnij ryad bukv)
   30-38                Alt-A - Alt-L (srednij ryad bukv)
   44-50                Alt-Z - Alt-M (nizhnij ryad bukv)
   59-68                Funkcional'nye klavishi F1 - F10
   71                   Home
   72                   Cursor-up (strelka vverh)
   73                   PgUp
   75                   Cursor-left (strelka vlevo)
   77                   Cursor-right (strelka vpravo)
   79                   End
   80                   Cursor-down (strelka vniz)
   81                   PgDn
   82                   Ins
   83                   Del
   84-93                F1-F10 + Shift
   94-103               F1-F10 + Ctrl
   104-113              F1-F10 + Alt
   114                  Ctrl + PrtSc
   115                  Ctrl + Cursor-left
   116                  Ctrl + Cursor-right
   117                  Ctrl + End
   118                  Ctrl + PgDn
   119                  Ctrl + Home
   120-131              Alt + 1 - Alt + = (verhnij ryad)
   132                  Ctrl + PgUp







   V  etoj glave rassmotreny monohromnyj adaptor, cvetnoj  grafi-
cheskij adaptor, videosistema  PCjr i uluchshennyj graficheskij adap-
ter (EGA).  Vse 4 sistemy baziruyutsya na mikrosheme Motorola  6845
CRTC (cathode ray  tube  controller);  hotya EGA na samom dele is-
pol'zuet zakaznuyu mikroshemu, osnovannuyu na principah 6845.   |ta
mikroshema vypolnyaet massu  tehnicheskih  zadach, kotorye obychno ne
interesuyut  programmista.  Odnako, ona takzhe ustanavlivaet  rezhim
ekrana, upravlyaet kursorom i (dlya cvetnogo graficheskogo adaptora)
upravlyaet cvetom. Mikroshema legko programmiruetsya napryamuyu, hotya
procedury operacionnoj sistemy  pozvolyayut  upravlyat' bol'shinstvom
ee  dejstvij.  PCjr imeet vspomogatel'nuyu mikroshemu dlya displeya,
"video gate array" (massiv vorot displeya),  kotoraya obsuzhdaetsya v
etom  razdele vmeste s 6845.  EGA imeet arhitekturu, otlichayushchuyusya
ot vseh ostal'nyh, poetomu on obsuzhdaetsya  otdel'no. Sredi ne-EGA
sistem imeetsya sovmestimost' po ispol'zovaniyu adresov portov,  no
est' i nekotorye  vazhnye  otlichiya.   Nekotorye  adresa portov EGA
takie zhe, kak i u drugih sistem.
   Vse  videosistemy  ispol'zuyut bufera, v  kotorye  otobrazhayutsya
dannye dlya izobrazheniya na ekrane.  |kran periodicheski obnovlyaetsya
skanirovaniem  etih  dannyh.  Razmer i raspolozhenie etih  buferov
menyaetsya s sistemoj, rezhimom ekrana,  a takzhe kolichestvom zaranee
otvedennoj  pamyati.   Kogda v bufere hranitsya  neskol'ko  obrazov
ekrana, to kazhdyj otdel'nyj  obraz nazyvayut displejnoj stranicej.
Nizhe privedena korotkaya svodka:

Monohromnyj adaptor

   Monohromnyj  adaptor imeet 4K bajt pamyati na plate, nachinaya  s
adresa B0000H (t.e.  B000:0000).  |toj  pamyati hvataet tol'ko dlya
hraneniya odnoj 80-simvol'noj stranicy teksta.

Cvetnoj graficheskij adaptor.

   Cvetnoj  graficheskij  adaptor imeet 16K bajt pamyati na  plate,
nachinaya s adresa pamyati B8000H.  |togo dostatochno dlya otobrazheniya
odnogo graficheskogo ekrana, bez stranic, ili ot chetyreh do vos'mi
ekranov teksta, v zavisimosti ot chisla simvolov v stroke - 40 ili
80.

PCjr.

   PCjr  imeet videosistemu, kotoraya na samom dele yavlyaetsya uluch-
shennoj versiej cvetnogo graficheskogo adaptora. Ona unikal'na tem,
chto ispol'zuet dlya videobufera obychnuyu operativnuyu pamyat'  siste-
my. Kogda BIOS inicializiruet sistemu, to verhnie 16K ustanovlen-
noj  pamyati otvodyatsya pod bufer terminala.  Takim  obrazom  adres
bufera zavisit ot togo  skol'ko  pamyati  imeetsya  v sisteme.  Dlya
dobavochnyh  displejnyh stranic mogut byt' otvedeny bloki pamyati v
drugih mestah, a takzhe nachal'nyj ob®em  mozhet byt' umen'shen do 4K
i byla podderzhka tol'ko odnogo ekrana teksta.


EGA.

   EGA  mozhet byt' snabzhen 64K, 128K ili 256K pamyati.  Krome  is-
pol'zovaniya v kachestve videobufera eta pamyat' mozhet takzhe hranit'
bitovye  opisaniya  vplot'  do  1024  simvolov  (kak  ob®yasneno  v
[4.3.4]). Startovyj adres  bufera  displeya programmiruem, poetomu
bufer nachinaetsya s adresa A000H dlya uluchshennyh graficheskih  rezhi-
mov, i s B000H i B800H dlya  sovmestimosti  so standartnymi monoh-
romnym i cvetnym graficheskim rezhimami.  V bol'shinstve sluchaev EGA
zanimaet dva segmenta  s  adresami  ot A000H do BFFFH, dazhe kogda
imeetsya 256K pamyati.  |to vozmozhno, poskol'ku v nekotoryh rezhimah
dva ili bolee bajtov pamyati displeya schityvayutsya iz odnih i teh zhe
adresov.   Dostupnoe chislo stranic zavisit kak ot rezhima  ekrana,
tak i ot kolichestva imeyushchejsya pamyati.  Vsledstvie svoej slozhnosti
EGA imeet PZU na 16K bajt, kotoroe zamenyaet i rasshiryaet procedury
raboty s terminalom BIOS. Nachalo oblasti PZU - adres C000:0000.

   V tekstovyh rezhimah  bufera  nachinayutsya  s  dannyh dlya verhnej
stroki ekrana, nachinaya s levogo ugla.  Dal'nejshie dannye  pereno-
syatsya s pravogo konca odnoj  stroki na levyj konec sleduyushchej, kak
budto  ekran  predstavlyaetsya  odnoj bol'shoj strokoj -  i s  tochki
zreniya videobufera tak ono i  est'.  Odnako v graficheskih rezhimah
bufer mozhet byt' razdelen na 2 ili 4 chasti.  U cvetnogo grafiches-
kogo adaptora i PCjr razlichnye chasti  bufera soderzhat informaciyu,
otnosyashchuyusya  k kazhdoj vtoroj ili kazhdoj chetvertoj linii tochek  na
ekrane.  U EGA kazhdaya chast'  bufera soderzhit odin bit iz dvuh ili
chetyreh, kotorye opredelyayut cvet dannoj tochki ekrana.
   Pri  vyvode teksta razlichnye videosistemy rabotayut  odinakovo.
Dlya ekrana otvoditsya 4000 bajtov, tak chto na kazhduyu iz 2000 pozi-
cij  ekrana prihoditsya 2 bajta (25 strok * 80 simvolov).   Pervyj
bajt soderzhit kod  ASCII.   Apparatura  displeya preobrazuet nomer
koda  ASCII  v  svyazannyj s nim simvol i posylaet ego  na  ekran.
Vtoroj bajt (bajt atributov) soderzhit  informaciyu o tom, kak dol-
zhen  byt' vyveden dannyj simvol.  Dlya monohromnogo displeya on us-
tanavlivaet budet li dannyj  simvol  podcherknut, vydelen yarkost'yu
ili negativom, ili ispol'zuet kombinaciyu etih atributov. V cveto-
vyh sistemah  bajt  atributov  ustanavlivaet  osnovnoj  i fonovyj
cveta simvola.  V lyubom sluchae Vasha programma mozhet pisat' dannye
pryamo v bufer terminala, chto znachitel'no povyshaet skorost' vyvoda
na ekran.
   Vse  sistemy, krome monohromnoj, predostavlyayut  nabor  cvetnyh
graficheskih rezhimov,  kotorye  otlichayutsya  kak razresheniem, tak i
chislom odnovremenno vyvodimyh cvetov. I PCjr i EGA mogut odnovre-
menno vyvodit' 16  cvetov,  prichem  EGA  mozhet vybirat' eti 16 iz
nabora 64 cvetov. Pri ispol'zovanii 16 cvetov kazhdaya tochka ekrana
trebuet chetyreh bit pamyati, poskol'ku  4 bita mogut hranit' chisla
ot 0 do 15.  Po analogii, chetyrehcvetnaya grafika trebuet tol'ko 2
bita na tochku. Dvuhcvetnaya  grafika mozhet upakovat' predstavlenie
vos'mi tochek v odin bajt videobufera.  Kolichestvo pamyati, trebue-
moe dlya dannogo rezhima ekrana  mozhet  byt'  legko vychisleno, esli
izvestno  kolichestvo vyvodimyh v etom rezhime  tochek i  kolichestvo
bit, neobhodimoe dlya opisaniya odnoj  tochki.  Tekst legko kombini-
ruetsya  s grafikoj (BIOS risuet simvoly na graficheskom ekrane)  i
Vy mozhete sozdavat' svoi special'nye simvoly.





   Vse videosistemy stroyatsya vokrug mikroshemy kontrollera video-
terminala  Motorola  6845 (EGA  ispol'zuet  zakaznuyu  mikroshemu,
osnovannuyu na 6845). Mikroshema ispol'zuetsya vo mnogom analogichno
v  monohromnom  adaptore, v cvetnom adaptore i v PCjr; no EGA  ne
nastol'ko sovmestim i po etoj prichine my rekomenduem Vam izbegat'
pryamogo  programmirovaniya mikroshemy, kogda BIOS mozhet  vypolnit'
rabotu za Vas.  Govorya obshchimi slovami, mikroshema 6845 ustanavli-
vaet  videodisplej  v  odin iz neskol'kih  alfavitnocifrovyh  ili
graficheskih rezhimov. Ona vypolnyaet osnovnuyu rabotu po interpreta-
cii nomerov kodov ASCII i poisku dannyh dlya vyvoda  sootvetstvuyu-
shchih simvolov v mikrosheme  PZU  (a  inogda v operativnoj pamyati).
Ona dekodiruet znacheniya atributov cveta i sootvetstvenno ustanav-
livaet ekran. Ona takzhe sozdaet kursor i upravlyaet im. V arhitek-
ture  EGA chast' etih funkcij raspredelena mezhdu drugimi mikroshe-
mami.
   Mikroshema  6845 imeet 18 upravlyayushchih registrov, pronumerovan-
nyh ot 0 do 17.  Pervye 10  registrov  fiksiruyut gorizontal'nye i
vertikal'nye parametry displeya.  |ti registry, kak pravilo, nein-
teresny dlya programmistov, poskol'ku oni avtomaticheski ustanavli-
vayutsya BIOS pri izmenenii rezhima ekrana.  Ne sovetuem eksperimen-
tirovat' s etimi registrami, poskol'ku imeetsya vozmozhnost' ispor-
tit' terminal.  Registry imeyut razmer 8 bit, no nekotorye svyazany
v pary, chtoby hranit' 16-bitnye  velichiny.   Pary #10-11 i #14-15
ustanavlivayut  formu  [4.2.4] i mestopolozhenie  [4.2.1]  kursora.
Para #12-13 upravlyaet  stranicami  displeya  [4.5.3].  Para #16-17
soobshchaet  poziciyu svetovogo pera [7.3.2].  Bol'shinstvo  registrov
dostupno tol'ko dlya zapisi; tol'ko registr adresa kursora mozhno i
chitat' i pisat', a registr svetovogo pera prednaznachen tol'ko dlya
chteniya. EGA imeet 6 dobavochnyh  registrov, kotorye svyazany s teh-
nicheskimi detalyami.  Registr 20 naibolee interesen; on opredelyaet
kakaya liniya skanirovaniya v  stroke  simvola ispol'zuetsya dlya pod-
cherkivaniya.
   Dostup ko vsem 18 registram osushchestvlyaetsya cherez odin i tot zhe
port, adres kotorogo dlya monohromnogo  adaptora raven 3B5H.  |tot
adres  raven 3D5H dlya cvetnogo adaptora i PCjr (zametim, chto  vse
adresa portov dlya monohromnogo adaptora takie zhe, kak i dlya cvet-
nogo,  za isklyucheniem togo, chto srednej cifroj yavlyaetsya  B, a  ne
D). EGA ispol'zuet odin iz  etih  dvuh  adresov, v zavisimosti ot
togo, prisoedinen li k nemu cvetnoj ili monohromnyj monitor.  Dlya
zapisi v registr  monohromnogo  adaptora  nado  snachala v registr
adresa,  raspolozhennyj v porte 3B4H (3D4H dlya cvetnogo),  poslat'
nomer trebuemogo registra. Togda sleduyushchij bajt, poslannyj v port
s adresom 3B5H budet zapisan v etot registr.  Poskol'ku registry,
interesnye dlya programmista, ispol'zuyutsya poparno, to nado snacha-
la  zapisat'  v adresnyj registr, potom v  pervyj  registr  pary,
potom snova v  adresnyj  registr  i,  nakonec,  vo vtoroj registr
pary.  Poskol'ku adresa portov smezhnye, to legche vsego adresovat'
ih, ispol'zuya instrukcii INC i DEC, kak v sleduyushchem primere:

;---zapis' v registry 11 i 12 mikroshemy 6845 (dannye v BX)
   ;---vybiraem registr mladshego bajta
      MOV  DX,3B4H        ;port adresnogo registra
      MOV  AL,11          ;nomer registra dlya mladshego bajta
      OUT  DX,AL          ;posylaem nomer registra


   ;---posylaem bajt
      INC  DX             ;uvelichivaem adres porta
      MOV  AL,BL          ;berem mladshij bajt
      OUT  DX,AL          ;posylaem ego v registr 11
   ;---vybiraem registr starshego bajta
      DEC  DX             ;vosstanavlivaem adres porta
      MOV  AL,12          ;nomer registra dlya starshego bajta
      OUT  DX,AL          ;posylaem nomer registra
   ;---posylaem bajt
      INC  DX             ;uvelichivaem adres porta
      MOV  AL,BH          ;berem starshij bajt
      OUT  DX,AL          ;posylaem ego v registr 12

   U  monohromnogo  i cvetnogo adaptorov imeyutsya eshche  tri  porta,
kotorye vazhny dlya  programmistov.   Oni imeyut adresa 3B8H, 3B9H i
3BAH  dlya monohromnogo i 3D8H, 3D9H i 3DAH - dlya cvetnogo adapto-
ra. Pervyj ustanavlivaet rezhim ekrana, vtoroj - svyazan v osnovnom
s ustanovkoj cvetov ekrana, a tretij soobshchaet poleznuyu informaciyu
o statuse displeya.
   PCjr ispol'zuet ne vse eti adresa  analogichnym obrazom. Vmesto
etogo,  on derzhit chast' informacii, otnosyashchejsya k etim portam,  v
mikrosheme massiva vorot  displeya,  osnovnoe naznachenie kotoroj -
obespechit'  dopolnitel'noe upravlenie cvetami ekrana.   Dostup  k
massivu vorot displeya osushchestvlyaetsya cherez port s adresom 3DAH. U
cvetnogo  adaptora etot port vozvrashchaet bajt statusa; u PCjr etot
port takzhe vozvrashchaet bajt  statusa  pri ispol'zovanii instrukcii
IN, no on predostavlyaet dostup k massivu vorot, kogda ispol'zuet-
sya instrukciya OUT. Massiv vorot displeya imeet sleduyushchie registry:

         Nomer             Naznachenie

           0               rezhim upravleniya 1
           1               maska nabora cvetov (paletty)
           2               cvet granicy
           3               rezhim upravleniya 2
           4               sbros
           10H-1FH         naznachenie cvetov paletty

   Dostup ko vsem registram osushchestvlyaetsya cherez port 3DAH.  Sna-
chala nado poslat' v etot port nomer trebuemogo registra, a  zatem
znachenie etogo registra. Port  avtomaticheski  pereklyuchaetsya mezhdu
etimi  funkciyami  raboty s adresami i s dannymi.  CHtoby on  nachal
ozhidat' vvod adresa, nado  prochitat'  ego. Otdel'nye registry ob-
suzhdayutsya v razlichnyh mestah etoj glavy.
   Osobyj interes predstavlyayut 16 registrov paletty s nomerami ot
10H do 1FH. Kazhdyj registr imeet razmer vsego 4 bita, chto kak raz
dostatochno,  chtoby  hranit' 16 kodovyh nomerov dlya  16  vozmozhnyh
cvetov. Dlya kazhdoj pozicii simvola ili tochki na ekrane videobufer
soderzhit  dannye, ukazyvayushchie kakim cvetom dolzhen vyvodit'sya etot
ob®ekt.  |tu informaciyu nazyvayut dannymi atributov.  V otlichie ot
cvetnogo graficheskogo adaptora PCjr ne ispol'zuet dannye  atribu-
tov dlya neposredstvennogo  opredeleniya cveta, kotoryj budet vyvo-


dit'sya.   Vmesto etogo dannye atributov yavlyayutsya  ukazatelyami  na
odin iz 16 registrov paletty,  a  chislo,  soderzhashcheesya v etom re-
gistre,  opredelyaet kakim cvetom budet vyvodit'sya dannyj  simvol.
Pri takom metode, programme  nuzhno  izmenit' tol'ko ustanovku re-
gistra paletty, i vse simvoly ili tochki s sootvetstvuyushchim atribu-
tom izmenyat svoj cvet. Registry paletty rabotayut vo vseh rezhimah,
kak tekstovyh, tak i graficheskih.
   EGA  raspredelyaet  eti funkcii mezhdu  mikroshemoj  kontrollera
atributov (adres porta 3C0H)  i  dvumya  mikroshemami  kontrollera
grafiki (adresa portov 3CCH-3CFH).  Kontroller atributov soderzhit
16 registrov paletty EGA,  pronumerovannyh  ot 00 do 0FH. |ti re-
gistry  mogut soderzhat' 6-bitnye kody cvetov, kogda EGA svyazan  s
uluchshennym  cvetnym  displeem,  poetomu  mogut  byt' ispol'zovany
lyubye 16 cvetov iz nabora 64-h. V [4.4.1] pokazano kak programmi-
rovat' registry paletty dlya PCjr i EGA.





   Monohromnyj adaptor podderzhivaet odin rezhim terminala, cvetnoj
graficheskij - sem', PCjr -  desyat',  a EGA - dvenadcat'.  Sistema
PCjr bolee gibkaya, chem monohromnyj ili cvetnoj adaptory, poskol'-
ku ona predostavlyaet  shirokij  vybor  cvetov  v rezhimah s dvumya i
chetyr'mya  cvetami, a takzhe serye teni v cherno-belom rezhime.   EGA
eshche bolee slozhen,  podderzhivaya  palettu  iz 64 cvetov, grafiku na
monohromnom displee i vyvod v 43 stroki.  Nizhe priveden  perechen'
razlichnyh rezhimov:

   Nomer         Rezhim                                       Adaptory

    0        40*25 (320*200) B&W alfavitnocifrovoj         cvetnoj, PCjr, EGA
    1        40*25 (320*200) cvetnoj alfavitnocifrovoj     cvetnoj, PCjr, EGA
    2        80*25 (640*200) B&W alfavitnocifrovoj         cvetnoj, PCjr, EGA
    3        80*25 (640*200) cvetnoj alfavitnocifrovoj     cvetnoj, PCjr, EGA
    4        320*200 4-cvetnaya grafika                     cvetnoj, PCjr, EGA
    5        320*200 B&W grafika (4 teni na PCjr)          cvetnoj, PCjr, EGA
    6        640*200 B&W grafika                           cvetnoj, PCjr, EGA
    7        80*25 (720*350) B&W alfavitnocifrovoj         monohromnyj, EGA
    8        160*200 16-cvetnyj grafika                    PCjr
    9        320*200 16-cvetnyj grafika                    PCjr
    A        640*200 4-cvetnyj grafika                     PCjr
    B        zarezervirovan dlya EGA
    C        zarezervirovan dlya EGA
    D        320*200 16-cvetnyj grafika                    EGA
    E        640*200 16-cvetnyj grafika                    EGA
    F        640*350 4-cvetnaya grafika na monohromnom      EGA
   10        640*350 4- ili 16-cvetnaya grafika             EGA

   EGA  razreshaet imet' 8 stranic v rezhime 7 - standartnom monoh-
romnom tekstovom rezhime. Rezhimy 0-6 polnost'yu sovmestimy, ispol'-
zuya pamyat' odinakovym obrazom.  Pri uslovii, chto pereklyuchateli na
EGA ustanovleny dlya raboty  s  uluchshennym  cvetnym displeem firmy
IBM,  tradicionnye tekstovye rezhimy vyvodyatsya s vysokim  razreshe-
niem, ispol'zuya risunok  simvolov,  sostoyashchij iz 8*14 tochek, a ne
obychnye 8*8.
   BIOS  hranit  odnobajtnuyu peremennuyu po  adresu  0040:0049,  v
kotoroj  soderzhitsya  nomer  tekushchego   rezhima.   Bajt  po  adresu
0040:004A daet chislo simvolov v stroke v tekstovom rezhime.

   Vysokij uroven'.

   Bejsik  ispol'zuet  operatory SCREEN i  WIDTH  dlya  upravleniya
rezhimom ekrana. PCjr  ispol'zuet  eti  operatory neskol'ko drugim
sposobom,  chem monohromnyj i cvetnoj adaptory, i eto budet obsuzh-
dat'sya nizhe. Odin operator SCREEN ustanavlivaet rezhim dlya cvetno-
go  adaptora.   Za operatorom stoit nomer  koda,  ustanavlivayushchij
razreshenie, gde:

   0   tekstovyj rezhim
   1   graficheskij rezhim srednego razresheniya
   2   graficheskij rezhim vysokogo razresheniya


SCREEN 1  ustanavlivaet  graficheskij  rezhim  srednego razresheniya.
Vtoroj parametr vklyuchaet i vyklyuchaet cvet. |tot parametr ne imeet
smysla dlya rezhima vysokogo  razresheniya  na cvetnom adaptore, pos-
kol'ku razreshen tol'ko cherno-belyj rezhim. Dlya tekstovyh rezhimov 0
v kachestve  vtorogo  parametra  vyklyuchaet  cvet,  a 1 - vklyuchaet.
Operator  SCREEN  0,0 ustanavlivaet tekstovyj cherno-belyj  rezhim.
Dlya graficheskogo rezhima situaciya obratnaya: 0 - vklyuchaet cvet, a 1
- vyklyuchaet.  Poetomu operator SCREEN 1,1 ustanavlivaet cherno-be-
lyj graficheskij rezhim srednego razresheniya.
   Vse rezhimy pervonachal'no pokazyvayutsya  cherno-belymi.  Operator
COLOR  (sm.   [4.1.3]) dolzhen byt' ispol'zovan,  chtoby  zakrasit'
ekran fonovym cvetom. V graficheskom rezhime odnogo operatora COLOR
dostatochno,  chtoby izmenit' ves' fon na ukazannyj cvet.   No  dlya
tekstovogo rezhima Vy  dolzhny  posle  operatora COLOR ispol'zovat'
operator CLS.
   V  tekstovyh  rezhimah v stroke mozhet byt' 40 ili 80  simvolov.
Dlya ustanovki trebuemogo chisla  simvolov  v stroke nado ispol'zo-
vat' operator WIDTH.  WIDTH 40 daet 40 simvolov v stroke, a WIDTH
80 - 80. Drugie znacheniya nedopustimy. Esli operator WIDTH ispol'-
zuetsya v graficheskom rezhime (SCREEN 1 ili SCREEN 2), to WIDTH  40
perevodit ekran v rezhim srednego razresheniya, a WIDTH 80 - v rezhim
vysokogo razresheniya. Vot neskol'ko primerov:

100 SCREEN 0,1: WIDTH 40  'cvetnoj tekstovyj rezhim s 40 simvolami

100 SCREEN 0,1: WIDTH 40  'cvetnoj displej kak monohromnyj

100 SCREEN 0,1: WIDTH 40  'cvetnaya grafika srednego razresheniya
 .
 .
500 WIDTH 80              'perevodim v rezhim vysokogo razresheniya

   Monohromnyj monitor mozhet byt' pereveden v rezhim 40 simvolov v
stroke operatorami SCREEN 0: WIDTH 40.  Dlya vosstanovleniya rezhima
s  80  simvolami vvedite WIDTH 80.  V rezhime s 40  simvolami  oni
sohranyayut svoyu obychnuyu shirinu, poetomu budet ispol'zovat'sya tol'-
ko levaya chast' ekrana.  Stroka perenositsya posle 40-go stolbca  i
nevozmozhno pomestit' kursor  v  pravuyu  polovinu ekrana s pomoshch'yu
operatora  LOCATE.  CLS chistit tol'ko levuyu chast' ekrana.  Trudno
predstavit' programmu, kotoraya  ispol'zovala  by eto svojstvo, no
ono  dejstvitel'no  pozvolyaet programme prinimat'  vvod  (skazhem,
cherez operator INPUT), v  to  vremya  kak  pol'zovatel' prodolzhaet
pechatat' v levoj polovine ekrana, ostavlyaya pravuyu polovinu ekrana
dlya vozmozhnoj korrektirovki  vvodimoj  informacii. Pri etom lyuboj
vyvod  v pravuyu polovinu ekrana vozmozhen tol'ko pryamogo obrashcheniya
k pamyati displeya, kak ob®yasneno v [4.3.1].
   PCjr ispol'zuet v Bejsike 7 nomerov rezhimov:

   Nomer                   Rezhim

     0       tekstovyj rezhim, shirina mozhet byt' 40 ili 80
     1       4-cvetnaya grafika srednego razresheniya
     2       2-cvetnaya grafika vysokogo razresheniya
     3       16-cvetnaya grafika nizkogo razresheniya
     4       4-cvetnyj rezhim srednego razresheniya
     5       16-cvetnyj rezhim srednego razresheniya
     6       4-cvetnaya rezhim vysokogo razresheniya


   Poslednie  chetyre rezhima trebuyut disketty s Bejsikom.   Razmer
stranicy opredelyaet kolichestvo pamyati, trebuemoe dlya odnogo ekra-
na (displejnye stranicy obsuzhdayutsya v [4.5.3]).  Programma dolzhna
otvesti sootvetstvuyushchee  kolichestvo pamyati pered ustanovkoj rezhi-
ma.   |to delaetsya operatorom CLEAR.  Za operatorom CLEAR  dolzhny
sledovat' tri  chisla,  opredelyayushchie  otvodimuyu  pamyat', tret'e iz
etih chisel ustanavlivaet razmer videobufera (pervye dva parametra
obsuzhdayutsya v  [1.3.1]).   Naprimer,  razmer dlya videobufera 16K,
ustanavlivaemyj  po umolchaniyu, vydelyaetsya komandoj CLEAR ,,16384.
K sozhaleniyu, razmer videobufera ukazyvaetsya  v bajtah, poetomu on
ne  raven  kruglomu chislu tipa 4000 ili 32000, a raven  4096  ili
32768.  Pomnite, chto 2K =  2^11,  4K  = 2^12, 16K = 2^14, a 32K =
2^15.  Dlya vydeleniya treh stranic po 16K, vvedite CLEAR ,,3*2^14.
|tot operator dolzhen pomeshchat'sya  v  samom  nachale programmy, pos-
kol'ku pri ispol'zovanii operatora CLEAR vse peremennye  ochishchayut-
sya. Otmetim takzhe, chto pri  sozdanii neskol'kih stranic, stranica
0 nachinaetsya s mladshih adresov pamyati.
   K  momentu  vyhoda etoj knigi Bejsik ne podderzhivaet  dopolni-
tel'nye rezhimy terminala EGA. V [4.3.3] privedena podprogramma na
mashinnom yazyke, kotoraya pozvolit Vam ustanovit' eti rezhimy.

   Srednij uroven'.

   Funkciya  0  preryvaniya 10H ustanavlivaet rezhim displeya.  V  AL
dolzhen nahodit'sya nomer rezhima ot  0 do A. CHtoby ustanovit' cvet-
noj graficheskij rezhim srednego razresheniya nado:

   MOV  AH,0       ;nomer funkcii
   MOV  AL,4       ;nomer trebuemogo rezhima
   INT  10H        ;ustanavlivaem rezhim

Dlya  opredeleniya tekushchego graficheskogo rezhima  nado  ispol'zovat'
funkciyu F preryvaniya  10H.  Preryvanie  vozvrashchaet nomer rezhima v
AL.   Ono takzhe daet nomer tekushchej stranicy displeya v BH i  chislo
simvolov v stroke v AH.

   MOV  AH,0FH          ;nomer funkcii
   INT  10H             ;poluchenie informacii o rezhime displeya
   MOV  MODE_NUMBER,AL  ;nomer rezhima v AL
   MOV  NUMBER_COLS,AH  ;chislo simvolov v stroke v AH
   MOV  CURRENT_PAGE,BH ;nomer tekushchej stranicy v BH

   MS DOS obespechivaet takzhe Esc-posledovatel'nosti dlya ustanovki
i sbrosa rezhimov displeya.  Dlya etogo neobhodimo, chtoby Vy predva-
ritel'no zagruzili drajver  ANSI.SYS,  kak ob®yasneno v prilozhenii
D.   Upravlyayushchaya stroka imeet vid ESC [=#h, gde # - nomer rezhima,
ukazannyj kak kod ASCII, a  ESC  oboznachaet  odin  simvol s kodom
ASCII 27. Naprimer:

;---v segmente dannyh
MED_RES_COLOR  DB   27, '[=4h$'
MED_RES_B&W    DB   27, '[=5h$'


;---ustanovka cvetnogo graficheskogo rezhima srednego razresheniya
   MOV  AH,9             ;nomer funkcii vyvoda stroki
   LEA  DX,MED_RES_COLOR ;DS:DX dolzhny ukazyvat' na stroku
   INT  21H              ;izmenenie rezhima

   Nizkij uroven'.

   V  dannom  punkte cvetnoj adaptor, monohromnyj adaptor i  PCjr
rassmatrivayutsya otdel'no,  poskol'ku  oni sushchestvenno otlichayutsya.
Cvetnoj  graficheskij adaptor imeet registr, kotoryj ustanavlivaet
rezhim displeya. On raspolozhen v porte s adresom 3D8H. Bity 0, 1, 2
i  4 hranyat ustanovku.  Bit 0 ustanavlivaet 40 simvolov v stroke,
kogda on raven 0 i 80 - kogda raven  1. Bit 1 ustanavlivaet disp-
lej v tekstovyj rezhim, kogda raven 0 i v graficheskij, kogda raven
1.  Bit 2 ustanavlivaet cvetnoj rezhim,  kogda raven 0 i cherno-be-
lyj, kogda raven 1. I, nakonec, bit 4 ustanavlivaet dlya grafiches-
kogo rezhima srednee razreshenie, kogda  raven 0 i vysokoe razreshe-
nie,  kogda raven 1 (bit 2 dolzhen byt' raven 1).  Nizhe  privedeny
vozmozhnye kombinacii:

   Rezhim                      bity:  5  4  3  2  1  0

0. 40*25, cherno-belyj, tekst         1  0  1  1  0  0
1. 40*25, cvetnoj, tekst             1  0  1  0  0  0
2. 80*25, cherno-belyj, tekst         1  0  1  1  0  1
3. 80*25, cvetnoj, tekst             1  0  1  0  0  1
4. 320*200, cherno-belyj, grafika     0  0  1  1  1  0
5. 320*200, cvetnoj, grafika         0  0  1  0  1  0
6. 640*200, cherno-belyj, grafika     0  1  1  1  1  0
                                     ł  ł  ł  ł  ł  tekst 80*25
                                     ł  ł  ł  ł  grafika 320*200
                                     ł  ł  ł  cherno-belyj
                                     ł  ł  razreshenie vyvoda
                                     ł  grafika 640*200
                                     miganie

   Izmenenie  etih bitov ne privodit k izmeneniyu rezhima  displeya.
Nuzhno eshche mnogo shagov,  vklyuchayushchih izmenenie parametrov pervyh 10
registrov  po adresu porta 3D5H.  BIOS zabotitsya obo  vsem  etom,
poetomu ne imeet smysla zanimat'sya vsej etoj deyatel'nost'yu. Odna-
ko inogda imeet  smysl  reinicializirovat'  registr  rezhima v ego
tekushchem rezhime, izmenyaya bity 3 i 5, kotorye na samom dele ne  ot-
vechayut za ustanovku rezhima.   Kogda bit 5 sbroshen v 0, to on zap-
reshchaet  atribut miganiya simvolov; v etom sluchae, esli starshij bit
bajta atributov ustanovlen,  to  eto  privodit  k vyvodu fonovogo
cveta vysokoj intensivnost'yu (sm.  primer v [4.1.3]). Bit 3 etogo
registra upravlyaet razresheniem vyvoda.  Kogda on raven 0, to ves'
ekran  zakrashivaetsya  v cvet ramki, no videobufer  ne  ochishchaetsya.
Vyvod mgnovenno vozvrashchaetsya, kogda  znachenie etogo bita menyaetsya
na 1. |to svojstvo polezno ispol'zovat' dlya izbezhaniya interferen-
cii ekrana pri sdvigah [4.5.1].  Nekotorye utility ispol'zuyut eto
svojstvo  dlya togo, chtoby zrya ne utomlyat' fosfornoe pokrytie tru-
bki terminala, kogda komp'yuter vklyuchen, no ne ispol'zuetsya. Otme-
tim takzhe, chto dva starshih bita registra ne ispol'zuyutsya.


   Monohromnyj  adaptor imeet sootvetstvuyushchij adres  porta  3B8H.
Imeyut znachenie tol'ko tri bita.  Bit 0 ustanavlivaet vysokoe raz-
reshenie,  kotoroe  yavlyaetsya edinstvennym dopustimym  rezhimom  dlya
monohromnogo displeya. Esli etot  bit raven 0, to komp'yuter peres-
taet rabotat'. Dva drugih znachashchih bita - eto bity 3 i 5, kotorye
upravlyayut razresheniem vyvoda i miganiem, v tochnosti tak zhe, kak i
dlya cvetnogo adaptora.
   PCjr  raspredelyaet informaciyu, soderzhashchuyusya v odnom porte  dlya
monohromnog i cvetnogo adaptora.   Massiv vorot displeya imeet dva
registra rezhima, nomera 0 i 3.  Dlya dostupa k etim registram nado
poslat' nomer registra v port  s  adresom  3DAH, a zatem zapisat'
dannye  po  tomu zhe adresu (chtenie etogo porta obespechivaet,  chto
pervaya zapis' v nego budet  vosprinyata,  kak ukazanie nomera tre-
buemogo registra). Vot znachenie bitov etih registrov:

Registr 0:
   bit 0   1 = tekst, 80*25 i rezhimy 5 i 6, inache 0
       0   1 = graficheskij rezhim, 0 = tekstovyj
       0   1 = zapret cvetov, 0 = razreshenie cvetov
       0   1 = razreshenie vyvoda, 0 = zapret vyvoda
       0   1 = 16-cvetnyj rezhim, 0 = vse ostal'nye rezhimy

Registr 3:
   bit 0   vsegda 0
       1   1 = razreshenie miganiya, 0 = 16 fonovyh cvetov
       2   vsegda 0
       3   1 = 2-cvetnaya grafika, 0 = vse ostal'nye rezhimy

Kak  i v dvuh predydushchih sluchayah, ne stoit ustanavlivat' eti  re-
gistry pryamo iz programmy,  tak  kak  nuzhno  eshche mnogo raboty dlya
programmirovaniya  mikroshemy  6845.  No kazhdyj iz etih  registrov
soderzhit bit, kotoryj inogda  prihoditsya  programmno  modificiro-
vat', a poskol'ku eti registry tol'ko dlya zapisi, to Vam  neobho-
dimo ponimat' znachenie vseh ih bitov.   |ti bity - bit razresheniya
vyvoda  v  registre 0 i bit razresheniya miganiya v registre 3.   Ih
dejstvie bylo opisano ranee i  vozmozhnoe  ih ispol'zovanie eshche ne
raz budet obsuzhdat'sya v etoj glave (v [4.5.1] i [4.1.3]).
   EGA  imeet  dva registra, upravlyayushchih rezhimom  displeya.   Odin
imeet adres porta 3D5H.  |tot registr ne soderzhit ni odnogo bita,
svyazannogo  s  chem-libo drugim, poetomu net nikakih prichin  obra-
shchat'sya k nemu.  Vtoroj registr  imeet adres porta 3C0H i soderzhit
bit, kotoryj vybiraet budet li bit 7 bajta atributov sootvetstvo-
vat' miganiyu ili vysokoj intensivnosti. |tot vopros obsuzhdaetsya v
[4.1.3].





   Kogda  displej  ustanovlen v tekstovyj rezhim v lyuboj iz  video
sistem, to kazhdoj pozicii  simvola  na ekrane otvoditsya dva bajta
pamyati.   Pervyj bajt soderzhit nomer koda ASCII koda  simvola,  a
vtoroj - atributy simvola.  Cvetnoj adaptor i PCjr mogut vyvodit'
v  cvete,  kak sam simvol, tak i vsyu oblast', otvedennuyu  dannomu
simvolu (fonovyj  cvet).   Monohromnyj  adaptor  ogranichen tol'ko
chernym  i  belym cvetom, no on  mozhet  generirovat'  podcherknutye
simvoly, chego ne mogut delat'  cvetnoj  adaptor  i PCjr.  Vse tri
sistemy mogut vydavat' migayushchie simvoly i negativnoe izobrazhenie.
Vse tri sistemy mogut takzhe sozdavat' simvoly s vysokoj intensiv-
nost'yu,  hotya dlya cvetnogo adaptora i PCjr  povyshennaya  intensiv-
nost' simvola na  samom  dele  privodit  k  drugomu cvetu (vosem'
osnovnyh  cvetov  imeyut versii s povyshennoj  intensivnost'yu,  chto
daet nabor 16 cvetov).  EGA  umeet  delat' vse, chto mogut vse os-
tal'nye sistemy i mnogoe drugoe. V chastnosti, na uluchshennom disp-
lee on mozhet  vyvodit'  podcherknutye  cvetnye  simvoly, poskol'ku
matrica izobrazheniya simvolov 8*14 daet takuyu vozmozhnost'.

   Atributy cveta:
   Dlya  ukazaniya cvetov ekrana odni i te zhe nomera kodov  ispol'-
zuyutsya v Bejsike i preryvaniyami operacionnoj sistemy. Oni takie:

          0 - chernyj                  8 - seryj
          1 - sinij                   9 - goluboj
          2 - zelenyj                10 - svetlozelenyj
          3 - cian                   11 - svetlyj cian
          4 - krasnyj                12 - svetlokrasnyj
          5 - magenta                13 - svetlaya magenta
          6 - korichnevyj             14 - zheltyj
          7 - belyj                  15 - yarkobelyj

Mladshie chetyre bita  bajta  atributov  ustanavlivayut  cvet samogo
simvola  (bit 3 vklyuchaet vysokuyu intensivnost').   Sleduyushchie  tri
bita ustanavlivayut fon  simvola.   I  pri obychnyh obstoyatel'stvah
starshij bit vklyuchaet i vyklyuchaet miganie. Takim obrazom:

kogda bit 0 = 1, sinij vklyuchaetsya v osnovnoj cvet
          1 = 1, zelenyj vklyuchaetsya v osnovnoj cvet
          2 = 1, krasnyj vklyuchaetsya v osnovnoj cvet
          3 = 1, simvol vyvoditsya s vysokoj intensivnost'yu
          4 = 1, sinij vklyuchaetsya v fonovyj cvet
          5 = 1, zelenyj vklyuchaetsya v fonovyj cvet
          6 = 1, krasnyj vklyuchaetsya v fonovyj cvet
          7 = 1, simvoly migayut

   Bity  0-2  i 4-6 soderzhat odni i te zhe komponenty  cvetov  dlya
samih simvolov i fona.  |ti trehbitnye gruppy pozvolyayut 8 vozmozh-
nyh  kombinacij.  Kogda vklyuchaetsya bit vysokoj intensivnosti,  to
dobavlyayutsya eshche 8 cvetov. SHestnadcat' vozmozhnyh cvetov poluchayutsya
iz etih ustanovok bitov sleduyushchim obrazom:


   Krasnyj  Zelenyj  Sinij  Nizkaya intensivnost'  Vysokaya

      0        0       0        chernyj            seryj
      0        0       1        sinij             svetlosinij
      0        1       0        zelenyj           svetlozelenyj
      0        1       1        cian              svetlyj cian
      1        0       0        krasnyj           svetlokrasnyj
      1        0       1        magenta           svetlaya magenta
      1        1       0        korichnevyj        zheltyj
      1        1       1        belyj             yarkobelyj

Mozhno  imet' 16 cvetov i dlya fonovogo cveta.  V etom sluchae bit 7
dolzhen sluzhit' ukazatelem  vysokoj  intensivnosti  dlya fona, a ne
ukazatelem miganiya simvolov.  Dlya cvetnogo adaptora nado izmenit'
bit 5 porta s adresom 3D8H v 0, kak pokazano nizhe. Poskol'ku etot
port  dostupen  tol'ko dlya zapisi, to vse ostal'nye  bity  dolzhny
byt'  pereustanovleny.  |ta  vozmozhnost'  dostupna  tol'ko v dvuh
sluchayah:  tekstovyh rezhimov s 40 i s 80 simvolami v stroke.   Dlya
rezhima s 80 simvolami nado poslat' v port chislo 9, a dlya rezhima s
40  simvolami  - chislo 8.  CHtoby vernut' miganie nado dobavit'  k
oboim etim znacheniyam 32. Dlya PCjr nado sbrosit' v 0 bit 1 regist-
ra 3 massiva vorot displeya.  Vse ostal'nye bity dolzhny byt' ravny
nulyu, krome nomera 3, kotoryj  dolzhen  byt' ustanovlen dlya rezhima
dvuhcvetnoj grafiki. Krome etogo rezhima, dlya ustanovki bita miga-
niya nado snachala prochitat' port s adresom 3DAH, chtoby podgotovit'
massiv  vorot displeya, zatem poslat' v nego 3, chtoby ukazat'  re-
gistr, i zatem poslat' 0, chtoby  ustanovit'  bit miganiya. Pri za-
vershenii  programmy vsegda nado vosstanavlivat' miganie, tak  kak
sleduyushchaya programma mozhet polagat'sya na eto.
   EGA takzhe mozhet  razreshat'/zapreshchat' miganie, hotya v etom slu-
chae  adres  porta 3C0H.  Snachal nado prochitat' port  3DAH,  chtoby
poluchit' dostup k adresnomu registru v 3C0H. zatem nado poslat' v
3C0H  10H, chtoby ukazat' sootvetstvuyushchij registr.  Nakonec,  nado
poslat' dannye po tomu zhe adresu.   Poskol'ku etot registr tol'ko
dlya zapisi, to vse bity dolzhny byt' pravil'no ustanovleny.  Miga-
nie vklyuchaetsya ustanovkoj  bita  3,  a  vyklyuchaetsya sbrosom etogo
bita.   Vse ostal'nye bity v cvetnom tekstovom rezhime dolzhny byt'
ravny 0.
   Dlya cvetnogo adaptora, kogda  simvoly  vyvodyatsya  na displej v
cvetnom graficheskom rezhime, to oni izobrazhayutsya v tekushchem fonovom
cvete.  Operatory, kotorye vyvodyat na ekran, kak v Bejsike, tak i
v  MS DOS (preryvanie 21H) ogranicheny vyvodom simvolov v  tret'em
cvete ispol'zuemoj paletty  (imeyutsya dve paletty iz treh cvetov -
sm.  [4.4.1]). V palette 0 simvoly zheltye/korichnevye, a v palette
1 oni belye.  Procedury  vyvoda  simvolov  BIOS (preryvanie 10H),
odnako,  mogut  ukazat' lyuboj iz treh cvetov paletty.   S  drugoj
storony, dlya PCjr, cvet naznachennyj  opredelennoj pozicii paletty
mozhet byt' izmenen, poetomu dlya vyvoda simvolov mogut ispol'zova-
ny lyubye cveta.
   Dlya  PCjr  cveta sootvetstvuyushchie dannym kodovym nomeram  mogut
byt' izmeneny.  Kazhdyj kodovyj nomer svyazan s registrom paletty v
massive vorot displeya [4.1.1].  |ti registry pronumerovany ot 10H
do 1FH, chto sootvetstvuet kodam  ot  0 do 15. Kazhdyj 4-bitnyj re-


gistr  soderzhit  chislo  v diapazone  0-15,  kotoroe  predstavlyaet
real'nyj cvet, vyvodimyj kogda  operator programmy vstrechaet odin
iz  kodovyh nomerov.  Naprimer, esli v kakom-to  meste  programmy
ukazano, chto simvol  dolzhen  vyvodit'sya  s  kodovym nomerom 0, to
cvet  vyvodimogo simvola opredelyaetsya kodom cveta,  hranyashchemsya  v
registre paletty 0. Nachal'noe  znachenie etogo registra 0000, poe-
tomu budet vyvodit'sya chernyj cvet.  No soderzhimoe etogo  registra
mozhet byt' izmeneno,  skazhem,  na  0001,  a v etom sluchae kodovyj
nomer  0 priveden k vyvodu sinim cvetom.  Kodovye nomera, ispol'-
zuemye v registrah paletty takie zhe,  kak i v operatorah program-
my.  Na ris.  4-1 pokazana nachal'naya ustanovka registrov  paletty
dlya vseh registrov,  krome  registra  dlya zelenogo cveta, kotoryj
izmenen tak, chtoby vyvodilsya cvet magenta.
   CHtoby  zaprogrammirovat'  registr paletty PCjr  nuzhno  snachala
poslat' ego nomer (ot 10H do  1FH)  v massiv vorot displeya, adres
porta kotorogo 3DAH.  Zatem nuzhno poslat' dannye po tomu zhe adre-
su. CHtoby byt' uverennym, chto  massiv gotov prinyat' nomer regist-
ra,  a ne dannye, nado snachala prochitat' iz porta 3DAH,  otbrosiv
prochitannoe.
   EGA takzhe ispol'zuet 16 registrov  paletty.  Oni raspolozheny v
porte  s  nomerom 3C0H, a nomera ih menyayutsya ot 00 do 0FH.   Nado
snachala prochitat' iz porta  3DAH,  chtoby  pereklyuchit' port na ego
adresnyj registr, zatem poslat' nomer registra paletty v 3C0H,  a
zatem poslat' dannye. Kogda  pereklyuchateli  na EGA ustanovleny na
uluchshennyj  rezhim (dlya uluchshennogo cvetnogo displeya IBM), to  pa-
letta mozhet byt' vybrana iz 64  cvetov.  V  etom sluchae ustanovka
registra  paletty imeet dlinu 6 bitov v formate  R'G'B'RGB.  Bity
RGB dayut temnye cvety, a bity R'G'B'  - cveta povyshennoj yarkosti.
Kogda  ustanovleny  i R' i R, naprimer, to eto  privodit k  ochen'
yarkomu krasnomu cvetu.  Bity mogut smeshivat'sya davaya novye otten-
ki. Esli registry paletty, prednaznachennye dlya 64 cvetov, ispol'-
zuyutsya ne v uluchshennom rezhime, to 4-j i 5-j bity registra ignori-
ruyutsya  i  soderzhimoe registrov rassmatrivaetsya po obychnoj  sheme
RGB.  Poskol'ku PCjr i EGA  ispol'zuyut registry paletty, to vybor
fonovogo cveta ne ogranichen ispol'zovaniem bita 7 bajta atributov
v kachestve bita miganiya.

Monohromnye simvoly:

   Monohromnye simvoly ispol'zuyut  bajt atributov neskol'ko bolee
strannym obrazom.  Kak i s atributami cveta, bity 0-2  ustanavli-
vayut osnovnoj cvet, a bity 4-6  -  fonovyj.  |ti cveta mogut byt'
tol'ko belym i chernym, so sleduyushchim sootvetstviem bitam:

   Bit      Bit     Bit     Osnovnoj atribut        Fonovyj
 6 ili 2  5 ili 1 4 ili 0

    0        0       0      chernyj                  chernyj
    0        0       1      podcherknutyj belyj      belyj
    0        1       0      belyj                   belyj
    0        1       1      belyj                   belyj
    1        0       0      belyj                   belyj
    1        0       1      belyj                   belyj
    1        1       0      belyj                   belyj
    1        1       1      belyj                   belyj


Normal'nyj  rezhim  belyj na chernom, kogda bity 0-2 ustanovleny  v
111, a bity 4-6 ustanovleny v  000.  Negativnoe  izobrazhenie soz-
daetsya obratnymi znacheniyami bitov. Simvoly vyvodyatsya s povyshennoj
yarkost'yu, kogda bit 3 ustanovlen v  1; ne sushchestvuet sposoba pri-
dat' povyshennuyu yarkost' fonu, kogda simvoly vyvodyatsya v  negativ-
nom izobrazhenii, a takzhe nedostupno podcherkivanie v negative.  Vo
vseh sluchayah, ustanovka v 1 bita  7 daet miganie simvolov.  Vsego
vozmozhno  tol'ko  10 kombinacij, kogda simvoly vidny.  Oni  mogut
byt' realizovany razlichnymi ustanovkami bitov. Nizhe privodyatsya po
odnoj iz vozmozhnyh ustanovok dlya kazhdogo sluchaya:

   Atribut                 Cepochka bitov       Geks    10-noe

   normal'nyj                00000111            7         7
   intensivnyj               00001111            F        15
   normal'nyj podcherknutyj   00000001            1         1
   intensivnyj podcherknutyj  00001001            9         9
   negativnyj                01110000           70       112
   normal'nyj migayushchij       10000111           87       135
   intensivnyj migayushchij      10001111           8F       143
   normal'nyj migayushchij podch. 10000001           81       129
   yarkij migayushchij podcherk.   10001001           89       137
   yarkij negativnyj          11110000           F0       240

   Vysokij uroven'.

   Bejsik  ustanavlivaet  cveta  i atributy  simvolov  operatorom
COLOR.  Vse operatory PRINT  i  WRITE,  kotorye sleduyut za dannym
operatorom  COLOR,  vypolnyayutsya s atributami,  ukazannymi v  etom
operatore. Cvet fona menyaetsya tol'ko dlya vyodimyh simvolov, no ne
dlya vsego ekrana.  Novyj operator COLOR ne vliyaet na to, chto bylo
vyvedeno ranee.
   Krome sluchaya monohromnogo  adaptora,  COLOR  3,4 ustanavlivaet
osnovnoj cvet simvola cian (#3), a fonovyj - krasnyj (#4). Diapa-
zon kodov osnovnyh cvetov 0-31,  prichem  chisla 0-15 sootvetstvuyut
cvetam,  perechislennym  v vysheprivedennoj tablice, a chisla  16-31
poluchayutsya pribavleniem k lyubomu iz etih kodov chisla 16, chto daet
tot zhe samyj cvet, no s miganiem simvolov.  (Pri miganii osnovnoj
cvet periodicheski menyaetsya  na  fonovyj,  v  to vremya kak fonovyj
cvet ostaetsya neizmennym.)
   Operatory PRINT i WRITE mogut takzhe vyvodit' simvoly na grafi-
cheskij ekran.  Pri etom  cvet  simvolov  - eto vsegda tretij cvet
tekushchej paletty, t.e.  zheltyj/korichnevyj dlya paletty 0 i belyj  -
dlya paletty 1.
   Otmetim, chto kogda Vy  nachinaete  rabotat' v cvetnom tekstovom
rezhime,  to ves' ekran cherno-belyj.  CHtoby zakrasit' ves' ekran v
fonovyj cvet, neobhodimo  ukazat'  operatorom COLOR ,2, naprimer,
zelenyj cvet i zatem ochistit' ekran komandoj CLS. Kogda Vy chisti-
te ekran po hodu vypolneniya  programmy, to neobhodimo, chtoby pos-
lednij  operator  COLOR  ustanovil fonovyj cvet takim,  kakim  Vy
hotite zakrasit' ves' ekran.
   Dlya monohromnogo displeya atributy  ustanavlivayutsya analogichnym
obrazom.   0  sootvetstvuet chernomu cvetu, a lyuboe iz  chisel  1-7
sootvetstvuet belomu. Takim  obrazom COLOR 0,7 ustanavlivaet cher-
noe izobrazhenie na belom fone (negativ), v to vremya kak COLOR 7,0


daet vyvod belyh simvolov  na  chernom  fone  (obychnaya ustanovka).
Imeetsya odno isklyuchenie: esli v kachestve osnovnogo cveta  ispol'-
zovat' kod 1, to budut vyvodit'sya podcherknutye simvoly.  Pribaviv
8  k lyubomu iz kodov osnovnogo cveta, poluchim yarkoe  izobrazhenie.
Pribaviv 16 k lyubomu iz  kodov  0-15,  poluchim  migayushchie simvoly.
Takim  obrazom  7+8+16=31 daet yarkoe migayushchee beloe  izobrazhenie.
Dlya fonovogo cveta dopustimy tol'ko znacheniya ot 0 do 7.
   Esli Vy ispol'zuete pryamoe  otobrazhenie  v  pamyat' [4.3.1], to
operator COLOR ne vliyaet na vyvod. Vmesto etogo Vy dolzhny vybrat'
trebuemuyu ustanovku atributov iz tablic  i pryamo prisvoit' znache-
nie  sootvetstvuyushchego bajta atributov operatorom POKE.   Pomnite,
chto bajty atributov vsegda zanimayut nechetnye pozicii v videobufe-
re.  Otobrazhenie v pamyat' pozvolyaet Vam imet' 16 fonovyh cvetov v
Bejsike (pri uslovii, chto  Vam  ne  nuzhny  migayushchie simvoly). Dlya
graficheskogo  adaptora  vvedite  OUT &H3D8,8, chtoby  starshij  bit
kazhdogo atributa dejstvoval kak bit yarkosti dlya fonovyh cvetov. V
sleduyushchem  primere v centre ekrana pechataetsya yarkokrasnyj "!"  na
svetlokrasnom fone.

100 DEF SEG = &HB800   'ukazyvaem na bufer cvetnogo displeya
110 OUT &H3D8,8        'ispol'zuem 16 fonovyh cvetov
120 POKE 1000,33       'pechataem ! v centre ekrana
130 POKE 1001,196      'krasnyj na svetlokrasnom (11000100)

Kak uzhe govorilos' vyshe PCjr  hranit  bit miganiya v massive vorot
displeya. Vot ta zhe programma dlya PCjr (no ona ne budet rabotat' v
rezhime dvuhcvetnoj grafiki):

100 DEF SEG = &HB800   'ukazyvaem na videobufer
110 X = INP(&H3AH)     'chitaem iz massiva vorot displeya
120 OUT &H3AH,3        'trebuem dostup k registru 3
130 OUT &H3AH,0        'sbrasyvaem vse bity etogo registra
140 POKE 1000,33       'pechataem ! v centre ekrana
150 POKE 1001,196      'krasnyj na svetlokrasnom (11000100)

Privedem eshche primer izmeneniya  naznacheniya cveta registra paletty.
Kod  cveta, kotoryj obychno vyvoditsya sinim (0001) sdelaem,  chtoby
on vyvodil cvet  magenta  (0101).   Nomer  registra massiva vorot
displeya, sootvetstvuyushchij kodu cveta 1 raven 11H.

100 X = INP (&H3AH)    'chitaem iz massiva vorot displeya
110 OUT &H3AH,&H11     'trebuem dostup k registru 11H
120 OUT &H3AH,5        'pomeshchaem tuda kod magenty (0101 = 5)

   Srednij uroven'.

   Preryvaniya  DOS i BIOS predostavlyayut ochen' bednye  vozmozhnosti
dlya raboty s cvetnym  tekstom.  Tol'ko  funkciya  9 preryvaniya 10H
prinimaet bajt atributov pri vyvode simvola. Funkciya A preryvaniya
10H vyvodit simvol bez ukazaniya  cveta  ili  atributa; ona prosto
pomeshchaet  simvol  v videobufer, ne trogaya  bajt  atributa,  takim
obrazom atributy sohranyayut svoe staroe znachenie. Funkciya D prery-
vaniya  10H  takzhe ostavlyaet netronutym bajt atributov.   Vse  eti
funkcii obsuzhdayutsya v [4.3.1].


   Funkcii vyvoda na ekran  DOS  preryvaniya  21H  vsegda  vyvodyat
beloe na chernom.  Dazhe esli dlya vsego ekrana ustanovlen nekotoryj
fonovyj cvet, to funkcii DOS  ustanavlivayut  atribut v normal'nyj
chernyj pri vyvode kazhdogo simvola.  Odnako imeetsya sposob preodo-
let' eto ogranichenie. MS  DOS  predostavlyaet  drajver  ustrojstva
ANSI.SYS, kotoryj mozhet interpretirovat' special'nye Esc-posledo-
vatel'nosti. V prilozhenii D ob®yasnyayutsya osnovy ego ispol'zovaniya.
Esc-posledovatel'nosti vyvodyatsya cherez funkciyu 9 preryvaniya  21H,
kotorye obychno vyvodyat stroku  simvolov  na ekran.  V etom sluchae
stroka sostoit iz simvola Esc, za kotorym sleduet [, a dalee odno
ili bolee kodovyh chisel iz nizheprivedennogo spiska. Stroka dolzhna
konchat'sya simvolom m i obychnym ogranichitelem $. Vot kodovye nome-
ra:

   0   vse atributy vyklyucheny (chernyj na belom)
   1   vklyuchena povyshennaya intensivnost'
   4   vklyucheno podcherkivanie
   5   vklyucheno miganie
   7   vklyucheno negativnoe izobrazhenie
   8   vse vklyucheno (pri etom simvoly nevidimy)

   30 chernyj osnovnoj cvet         40 chernyj fon
   31 krasnyj osnovnoj cvet        41 krasnyj fon
   32 zelenyj osnovnoj cvet        42 zelenyj fon
   33 zheltyj osnovnoj cvet         43 zheltyj fon
   34 sinij osnovnoj cvet          44 sinij fon
   35 osnovnoj cvet magenta        45 fon magenta
   36 osnovnoj cvet cian           46 fon cian
   37 belyj osnovnoj cvet          40 belyj fon

Otmetim, chto kogda funkcii MS  DOS  vyvodyat simvoly v graficheskom
rezhime, to oni obychno ispol'zuyut kod 3 tekushchej paletty. S pomoshch'yu
Esc-posledovatel'nostej mozhno ustanovit'  cvet simvola sootvetst-
vuyushchim  lyubomu  iz cvetov paletty.  Nado ukazyvat' 30 ili 31  dlya
fonovogo cveta, 32 ili 33 - dlya koda  1, 34 ili 35 - dlya koda 2 i
36  ili 37 - dlya koda 3.  V etom sluchae ne nado ukazyvat' fonovyj
cvet.
   V sleduyushchem primere na ekran  vyvodyatsya  dve  stroki s pomoshch'yu
funkcii  9 preryvaniya 21H.  Pervaya vyvoditsya sinim na krasnom,  a
vtoraya - migayushchim cianom na krasnom. Ne nado pereopredelyat' kras-
nyj v kachestve fonovogo cveta dlya vtoroj stroki, poskol'ku nazna-
cheniya cvetov dejstvuyut na vse posleduyushchie komandy vyvoda (vklyuchaya
funkcii  BIOS preryvaniya 10H), do teh por, poka ne budut  sdelany
drugie naznacheniya. Otmetim, kak  prosto  peremeshivat' komandy up-
ravleniya cvetom s vyvodom samih strok.

;---v segmente dannyh
STRING_1     DB   'The rain in Spain',0AH,0DH,'$'
STRING_2     DB   'Falls mainly on the plain$'
BLUE_RED     DB   27,'[34;41m$'
BLINK_CYAN   DB   27,'[5;36m$'


;---vyvod strok
   MOV  AH,9          ;funkciya vyvoda stroki
   LEA  DX,BLUE_RED   ;adres upravlyayushchej stroki v DX
   INT  21H           ;vse budet vydavat'sya sinim na krasnom
   LEA  DX,STRING_1   ;ukazyvaem na pervuyu stroku
   INT  21H           ;pechataem stroku
   LEA  DX,BLINK_CYAN ;adres vtoroj upravlyayushchej stroki
   INT  21H           ;menyaem cvet na migayushchij cian
   LEA  DX,STRING_2   ;ukazyvaem na vtoruyu stroku
   INT  21H           ;pechataem stroku

Vy  vsegda  dolzhny pozabotit'sya o tom,  chtoby  sbrosit'  atributy
cveta v normal'noe  sostoyanie  pered  zaversheniem programmy, pos-
kol'ku v protivnom sluchae oni budut dejstvovat' i na vyvod posle-
duyushchih programm. V konce sleduet  vyvesti Esc-posledovatel'nost',
ispol'zuyushchuyu kod nomer 0, kak ukazano vyshe.
   PCjr i EGA imeyut special'nuyu funkciyu BIOS dlya ustanovki soder-
zhimogo registrov paletty. |to podfunkciya 0 funkcii 10H preryvaniya
10H.  Nado pomestit' nomer registra paletty (ot 0 do 15) v BL,  a
znachenie koda cveta (takzhe ot  0  do  15) v BH, a zatem vypolnit'
preryvanie.  Podfunkciya 2 funkcii 10H ustanavlivaet vse  registry
paletty, a takzhe cvet  granicy,  ispol'zuya  17-bajtnyj massiv, na
kotoryj dolzhny ukazyvat' ES:DX.  Bajty 0-15 massiva pomeshchayutsya  v
registry paletty 0-15, a bajt  16  ustanavlivaet cvet granicy.  O
tom, kak otdel'no ustanovit' cvet granicy sm. [4.1.4].

   Nizkij uroven'.

   Kak  uzhe ob®yasnyalos' v razdele "Vysokij uroven'", nado  prosto
pomestit' trebuemoe znachenie bajta atributov v videobufer, za tem
simvolom,  k kotoromu eti atributy dolzhny  otnosit'sya.   Priveden
primer dlya cvetnogo adaptora ili PCjr.  V primere ustanavlivaetsya
tekstovyj  ekran 80*25 s 16 fonovymi cvetami, a zatem ekran  ini-
cializiruetsya v krasnyj cvet svetlosinem fone:

;---ustanovka 16 fonovyh cvetov v tekstovom rezhime 80*25
        MOV  AL,00001001B   ;ustanovka v 0 bita miganiya
        MOV  DX,3D8H        ;adres registra
        OUT  DX,AL          ;posylaem v registr
;---inicializiruem ves' ekran v krasnyj na svetlosinem fone
        MOV  AX,0B800H      ;ukazyvaem na videobufer
        MOV  ES,AX          ;
        MOV  CX,2000        ;zapisyvaem atribut v 2000 yacheek
        MOV  BX,1           ;BX ukazyvaet na bajt atributov
        MOV  AL,10010100B   ;znachenie bajta atributov
NEXT_CHAR:   MOV  ES:[BX],AL   ;posylaem atributy v bufer
        INC  BX             ;uvelichivaem ukazatel' na atributy
        INC  BX             ;
        LOOP NEXT_CHAR      ;pishem v sleduyushchuyu poziciyu





   Granica simvol'nogo ekrana mozhet imet' cvet, otlichnyj ot fono-
vogo cveta central'noj chasti ekrana. Mozhet byt' ispol'zovan lyuboj
iz 16 cvetov.  S drugoj storony, graficheskie ekrany tehnicheski ne
imeyut oblasti granicy.  Kogda  cvet fona ustanavlivaetsya v grafi-
cheskom  rezhime,  to ves' ekran, vklyuchaya oblast' granicy,  okrashi-
vaetsya v etot cvet.   Odnako,  operacii  vyvoda tochek na ekran ne
imeyut  dostupa  k oblasti granicy; esli bol'shuyu chast'  adresuemyh
tochek ekrana izmenit' v  nefonovyj  cvet,  to budet sozdana vidi-
most' granicy ekrana.

   Vysokij uroven'.

   Tretij  parametr  operatora Bejsika COLOR  ustanavlivaet  cvet
granicy.  Ispol'zuyutsya te zhe  samye kodovye nomera cvetov, prive-
dennye v [4.1.3].  Naprimer, dlya ustanovki granicy v  svetlosinij
cvet, nado napisat' COLOR  ,,8.  PCjr  krome  togo mozhet izmenyat'
cvet, za schet izmeneniya ustanovki registra paletty, sootvetstvuyu-
shchego kodu cveta, ukazannogo dlya cveta  granicy. Polnoe ob®yasnenie
sm. v [4.1.3].

   Srednij uroven'.

   Dlya vseh videosistem fonovyj cvet mozhet byt' ustanovlen  funk-
ciej BH, preryvaniya 10H. |ta funkciya ustanavlivaet takzhe osnovnye
cveta. CHtoby ukazat', chto nado izmenit' fonovyj cvet, nado pomes-
tit' 0 v BH, a kod cveta v BL i vypolnit' preryvanie. Krome togo,
PCjr  i EGA imeyut special'nuyu funkciyu dlya ustanovki fonovogo cve-
ta.  |to podfunkciya 1 funkcii 10H preryvaniya 10H.  Nado pomestit'
10H  v AH, 1 v AL i kod cveta v BH.  Nikakih znachenij ne  vozvra-
shchaetsya.

   Nizkij uroven'.

   Dlya cvetnogo  graficheskogo  adaptora  bity 0-3 porta 3D9H (Re-
gistr  vybora cveta) ustanavlivayut cvet granicy, kogda ekran  na-
hodmtsya v tekstovom rezhime. Kak obychno, naznachenie bitov v vosho-
dyashchem  poryadke - sinij (B), zelenyj (G), krasnyj (R) i  intensiv-
nost'. Poskol'ku etot adres  prednaznachen  tol'ko dlya zapisi, vse
ostal'nye bity etogo registra dolzhny byt' pravil'no  ustanovleny.
|to bit 4, kotoryj, esli ego ustanovit' v 1, privodit k tomu, chto
vse fonovye cveta budut vyvodit'sya s vysokoj intensivnost'yu.

;---ustanovka svetlosinego cveta granicy
   MOV  AL,00001001B   ;atribut svetlosinego cveta
   MOV  DX,3D9H        ;adres registra vybora cveta
   OUT  DX,AL          ;ustanavlivaem cvet granicy

   Dlya  PCjr massiv vorot displeya [4.1.1] imeet registr,  kotoryj
ustanavlivaet cvet granicy. |to 4-bitnyj registr, prichem bity 0-3
sootvetstvuyut sinemu, zelenomu, krasnomu i vysokoj intensivnosti,
kogda ustanovleny v  1.  Dlya  ustanovki  svetlosinego  cveta nado
poslat'  v registr 1001.  Registr cveta granicy - eto  registr  2


massiva vorot displeya.  CHtoby  poluchit'  dostup  k etomu registru
nado snachala poslat' 2 v port po adresu 3DAH.  Zatem nado poslat'
dannye po tomu zhe adresu.  CHtoby  byt'  uverennym, chto mikroshema
gotova  prinyat' nomer registra, a ne dannye, nado snachala  prochi-
tat' iz porta 3DAH. Sleduyushchij  primer  ustanavlivaet krasnyj cvet
granicy (bit 2 ustanovlen).

   MOV  DX,3DAH     ;adres porta massiva vorot displeya
   IN   AL,DX       ;chtenie dlya podgotovki mikroshemy
   MOV  AL,2        ;nomer trebuemogo registra
   OUT  DX,AL       ;posylaem v port
   MOV  AL,4        ;ustanavlivaems tol'ko bit 2
   OUT  DX,AL       ;ustanavlivaem cvet granicy

   Dlya  EGA cvet granicy ustanavlivaetsya  registrom  skanirovaniya
(overscan).  |to registr  nomer  11H  porta s adresom 3C0H.  Nado
snachala  prochitat'  etot port, chtoby pereklyuchit' ego na  adresnyj
registr, zatem poslat' tuda nomer 11H v kachestve indeksa, a zatem
poslat' dannye. Imeyut znachenie tol'ko mladshie 4 bita dannyh, esli
tol'ko EGA ne svyazan s uluchshennym  cvetnym displeem IBM, a v etom
sluchae imeyut znachenie mladshie 6 bitov, kotorye ustanavlivayut cvet
granicy.





   Ochistka  ekrana  sostoit prosto v zapisi probela v  kazhduyu  iz
pozicij ekrana (kod ASCII - 32). Odnako, esli pri vyvode na ekran
byli  ispol'zovany  nenormal'nye atributy, to dolzhny  byt'  takzhe
izmeneny i bajty  atributov.  Operacionnaya  sistema  obespechivaet
prostoj sposob ochistki tol'ko chasti ekrana.

   Vysokij uroven'.

   Bejsik  dlya ochistki ekrana ispol'zuet operator CLS.  Pri  etom
25-ya stroka vnizu ekrana  stanovitsya pustoj tol'ko esli byl ubran
spisok  znachenij funkcional'nyh klavish s pomoshch'yu komandy KEY OFF.
Bajty atributov ustanavlivayutsya  ravnymi  ASCII 7. V [4.5.1] dana
procedura  prokrutki,  kotoraya mozhet byt' ispol'zovana v  Bejsike
dlya ochistki okon na ekrane.

   Srednij uroven'.

   Operacionnaya sistema predostavlyaet  neskol'ko sposobov ochistki
ekrana.  Kakoj iz nih Vy vyberete zavisit ot togo, kakie sredstva
trebuyutsya programme dlya dostizheniya  drugih celej.  Pervyj metod -
eto  prosto sbros rezhima displeya, ispol'zuya funkciyu 0  preryvaniya
10H [4.1.2].  Dlya simvol'nogo  ekrana  kazhdaya poziciya zapolnyaetsya
probelom  (ASCII 32), a vse atributy ustanavlivayutsya  normal'nymi
(ASCII 7).  Obychno etot  metod  horosh  tol'ko v nachale programmy,
kogda  vse  ravno nado ustanavlivat' rezhim raboty  displeya.   Dlya
cvetnogo graficheskogo  adaptora  i  PCjr  reinicializaciya  rezhima
displeya privodit k katavasii na ekrane. |tot effekt otsutstvuet u
monohromnogo adaptora i EGA.

;---ochistka ekrana putem ustanovki novogo rezhima
   MOV  AH,0      ;nomer funkcii ustanovki rezhima displeya
   MOV  AL,2      ;kod rezhima 80*25 cherno-belogo
   INT  10H       ;ochistka ekrana

   Vtoroj metod sostoit v ispol'zovanii  funkcij 6 i 7 preryvaniya
10H,  kotorye sdvigayut ekran.  CHislo strok, na kotoroe nado sdvi-
nut' ekran pomeshchaetsya v AL  i  kogda  eto  chislo ravno nulyu ekran
ochishchaetsya.   Preryvanie pozvolyaet sdvigat' tol'ko  chast'  ekrana,
poetomu takim obrazom  mozhno  ochistit'  otdel'noe okno na ekrane.
Nado pomestit' koordinaty levogo verhnego ugla okna v CX, a koor-
dinaty pravogo nizhnego ugla v  DX  (nomer stroki v CH/DH, a nomer
stolbca  v CL/DL).  Pomestite atribut, s kotorym dolzhen chistit'sya
ekran v BH. Koordinaty otschityvayutsya ot 0.

;---ochistka okna mezhdu 3,4 i 13,15
   MOV  AH,6     ;ispol'zuem proceduru sdviga
   MOV  AL,0     ;chislo strok sdviga delaem ravnym nulyu
   MOV  BH,7     ;bajt atributov dlya zapolneniya
   MOV  CH,3     ;stroka dlya verhnego levogo ugla
   MOV  CL,4     ;stolbec dlya levogo verhnego ugla
   MOV  DH,13    ;stroka dlya nizhnego levogo ugla
   MOV  DL,15    ;stolbec dlya nizhnego levogo ugla
   INT  10H      ;chistim okno


   Tretij metod zaklyuchaetsya v ispol'zovanii  fukncii 9 preryvaniya
10H; kotoraya vyvodit simvol i atributy stol'ko raz, skol'ko  uka-
zano v CX. Znachenie 2000 chistit ves' ekran, esli kursor byl usta-
novlen  v 0,0, ispol'zuya metod pokazannyj v [4.2.1].   AH  dolzhen
soderzhat' simvol probela, AL - bajt atributov, a BH - nomer stra-
nicy displeya.

;---ustanovka kursora v levyj verhnij ugol ekrana
   MOV  AH,2     ;funkciya ustanovki kursora
   MOV  BH,0     ;nomer stranicy
   MOV  DX,0     ;koordinaty 0,0
   INT  10H      ;ustanavlivaem kursor
;---vyvod simvola probela 2000 raz
   MOV  AH,9     ;nomer funkcii
   MOV  CX,2000  ;chislo povtorenij vyvoda
   MOV  AL,' '   ;simvol probela v AL
   MOV  BL,7     ;atributy v BL
   INT  10H      ;ochistka ekrana

   Nakonec, DOS obespechivaet ochistku ekrana s pomoshch'yu special'nyh
Esc-posledovatel'nostej,  kotorye  rabotayut s drajverom ANSI.SYS.
Osnovnye svedeniya o nem privedeny v prilozhenii D.  |ti posledova-
tel'nosti - eto stroki,  nachinayushchiesya  s simvola Esc, a zavershayu-
shchiesya ogranichitelem $. Takie stroki vyvodyatsya funkciej 9 preryva-
niya 21H, pri etom DS:DX dolzhny ukazyvat' na pervyj simvol stroki.
DOS interpretiruet stroku ne vyvodya ee na displej.  CHtoby steret'
ves' ekran stroka dolzhna byt'  [2J.   CHtoby steret' konec stroki,
nachinaya ot pozicii kursora (vklyuchaya etu poziciyu), stroka [K.

;---v segmente dannyh
CLEAR_LINE   DB   27,'[K$'

;---ochistka konca stroki, nachinaya ot pozicii kursora
   MOV  AH,9          ;funkciya vyvoda stroki
   LEA  DX,CLEAR_LINE ;DX dolzhen ukazyvat' na nachalo stroki
   INT  21H           ;stiraem konec stroki

   Nizkij uroven'.

   Na  nizkom urovne nado prosto pomestit' simvoly probela i tre-
buemyj bajt atributov v  pamyat'   displeya,  ispol'zuya  instrukciyu
STOSW. Vot primer dlya monohromnogo displeya:

      MOV  AX,0B000H   ;ukazyvaem na pamyat' displeya
      MOV  ES,AX       ;
      MOV  DI,0        ;DI ukazyvaet na nachalo bufera
      MOV  AL,32       ;simvol probela
      MOV  AH,7        ;normal'nye atributy
      MOV  CX,2000     ;chislo povtorenij
REP   STOSW            ;posylaem AX v ES:DI 2000 raz





   Mashina  mozhet byt' osnashchena i monohromnym i cvetnym adaptorom,
ili odnim iz etih adaptorov  i  EGA.  Programma  mozhet  vybirat',
kakoj iz monitorov dolzhen byt' aktivnym, izmenyaya znacheniya bitov 4
i 5 v yachejke pamyati  0000:0410.   Ustanoviv  oba etih bita v 1 my
vybiraem monohromnyj adaptor.  Izmeniv ustanovku bitov 5-4 na  10
ustanavlivaem graficheskij  adaptor v rezhime 80 simvolov v stroke,
a na 01 - 40 simvolov v stroke.  I, nakonec, izmeniv bity na  00,
vybiraem EGA. Vo vseh sluchayah Vy dolzhny nemedlenno podat' komandu
ustanovki rezhima, poskol'ku BIOS imeet eshche ochen' mnogo registrov,
kotorye nado izmenit', prezhde chem displej budet rabotat' normal'-
no.
   Otmetim,  chto  hotya  operacionnaya sistema ne  mozhet  upravlyat'
odnovremenno dvumya monitorami, programmy mogut osushchestvlyat' vyvod
na oba displeya, ispol'zuya pryamoe otobrazhenie v pamyat' [4.3.1] dlya
adresov bufera neaktivnogo monitora.

   Vysokij uroven'.

   V Bejsike nado prosto ispol'zovat' sleduyushchij kod:

100 'Pereklyuchenie na monohromnyj displej
110 KEY OFF: CLS
120 WIDTH 40
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,M OR &H30
160 WIDTH 80
170 LOCATE,,1,12,13
180 KEY ON

100 'Pereklyuchenie na cvetnoj graficheskij displej (80 simvolov)
110 KEY OFF: CLS
120 WIDTH 80
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,(M AND &HCF) OR &H20
160 WIDTH 80
170 SCREEN 0
180 LOCATE,,1,6,7
190 KEY ON

100 'Pereklyuchenie na EGA (80 simvolov)
110 KEY OFF: CLS
120 WIDTH 80
130 DEF SEG = 0
140 M = PEEK(&H410)
150 POKE &H410,M AND &HCF
160 WIDTH 80
170 SCREEN 0
180 LOCATE,,1,6,7
190 KEY ON

Izmenite komandy WIDTH i  SCREEN,  chtoby  pereklyuchit'sya na drugie
nachal'nye rezhimy displeya.


   Nizkij uroven'.

   V assemblere, kak i v Bejsike, nado pryamo izmenit' bity 4 i  5
po adresu 0000:0410. Nado  sbrosit'  rezhim displeya srazu vsled za
izmeneniem.

;---pereklyuchenie na monohromnyj monitor
   SUB  AX,AX           ;obnulyaem AX
   MOV  ES,AX           ;ustanavlivaem ES na nachalo pamyati
   MOV  DL,ES:[410H]    ;poluchaem bajt po adresu 0000:0410
   OR   DL,00110000B    ;ustanavlivaem bity 4 i 5
   MOV  ES:[410H],DL    ;vozvrashchaem bajt
   MOV  AH,0            ;fukciya ustanovki rezhima displeya
   MOV  AL,0            ;monohromnyj rezhim 80*25
   INT  10H             ;ustanavlivaem rezhim

;---pereklyuchenie na cvetnoj monitor (40 simvolov)
   SUB  AX,AX           ;ustanavlivaem ES na nachalo pamyati
   MOV  ES,AX           ;
   MOV  DL,ES:[410H]    ;berem bajt po adresu 0000:0410
   AND  DL,11001111B    ;sbrasyvaem bity 4 i 5
   OR   DL,00010000B    ;ustanavlivaem bit 4
   MOV  ES:[410H],DL    ;vozvrashchaem bajt
   MOV  AH,0            ;funkciya ustanovki rezhima displeya
   MOV  AL,1            ;cvetnoj rezhim 40*25
   INT  10H             ;ustanavlivaem rezhim

;---pereklyuchenie na EGA
   SUB  AX,AX           ;ustanavlivaem ES na nachalo pamyati
   MOV  ES,AX           ;
   MOV  DL,ES:[410H]    ;berem bajt po adresu 0000:0410
   AND  DL,11001111B    ;sbrasyvaem bity 4 i 5
   MOV  ES:[410H],DL    ;vozvrashchaem bajt
   MOV  AH,0            ;funkciya ustanovki rezhima displeya
   MOV  AL,1            ;cvetnoj rezhim 40*25
   INT  10H             ;ustanavlivaem rezhim




   Kursor  sluzhit  dvum celyam.  Vo-pervyh, on  sluzhit  ukazatelem
mesta na ekrane, v  kotoroe  operatory  programmy  posylayut  svoj
vyvod. Vo-vtoryh, on obespechivaet vidimuyu tochku otscheta na ekrane
dlya pol'zovatelya programmy.  Tol'ko dlya vtorogo primeneniya kursor
dolzhen byt' vidimym.  Kogda kursor nevidim (vyklyuchen), to on  vse
ravno ukazyvaet na poziciyu  ekrana.   |to  vazhno, poskol'ku lyuboj
vyvod na ekran, podderzhivaemyj operacionnoj sistemoj,  nachinaetsya
s tekushchej pozicii kursora.
   Kursor  generiruetsya  mikroshemoj   kontrollera  displeya 6845,
opisannoj v [4.1.1]. |ta mikroshema imeet registry, ustanavlivayu-
shchie razmer i  polozhenie  kursora.  Mikroshema  6845 delaet tol'ko
mercayushchij  kursor, hotya imeyutsya programmnye sposoby sozdaniya  ne-
mercayushchego kursora  [4.2.6].  CHastota  mercaniya  kursora ne mozhet
byt'  izmenena.  V graficheskih rezhimah kursor ne vyvoditsya,  hotya
simvoly  pozicioniruyutsya  na  ekrane  temi  zhe samymi procedurami
ustanovki kursora, chto i v tekstovyh rezhimah.
   Kogda  videosistema  rabotaet v rezhime, dopuskayushchem  neskol'ko
displejnyh stranic, to  kazhdaya  stranica  imeet  svoj sobstvennyj
kursor  i  pri  pereklyuchenii mezhdu  stranicami  vosstanavlivaetsya
poziciya kursora, kotoruyu on zanimal, kogda bylo poslednee obrashche-
nie k vosstanavlivaemoj stranice. Nekotorye rezhimy displeya pozvo-
lyayut imet' do 8 displejnyh  stranic  i sootvetstvuyushchie im pozicii
kursora  hranyatsya v nabore vos'mi 2-bajtnyh peremennyh v  oblasti
dannyh BIOS, nachinaya s adresa  0040:0050H.   V  kazhdoj peremennoj
mladshij  bajt soderzhit nomer stolbca, otschityvaya ot 0, a  starshij
bajt soderzhit nomer stroki, takzhe  otschityvaya ot 0. Kogda ispol'-
zuetsya men'she chem 8 stranic, to ispol'zuyutsya peremennye, raspolo-
zhennye v bolee mladshih adresah pamyati.





   Dlya kursora mogut byt'  ustanovleny  absolyutnye koordinaty ili
koordinaty  otnositel'no ego tekushchej pozicii [4.2.2].  Absolyutnye
koordinaty mogut menyat'sya v  predelah  25  strok i 80 (inogda 40)
stolbcov.   YAzyki vysokogo urovnya obychno  otschityvayut  koordinaty
ekrana, nachinaya s 1, i takim obrazom poziciya levogo verhnego ugla
1,1.   YAzyk  assemblera vsegda nachinaet otschet s  nulya i  poziciya
levogo verhnego ugla 0,0.

   Vysokij uroven'.

   Bejsik numeruet stroki ot 1 do 25, a stolbcy ot 1 do 80.  For-
mat  operatora LOCATE, kotoryj ustanavlivaet poziciyu kursora  ta-
koj: LOCATE stroka,stolbec.   Esli ustanovki kursora ne delaetsya,
to  on  perehodit  v pervuyu poziciyu stroki posle  vvoda  vozvrata
karetki, a sdvig ekrana nachinaetsya posle togo, kak budet zapolne-
na  24-ya stroka.  CHtoby vyvesti v 25-yu stroku Vy dolzhny ispol'zo-
vat' LOCATE  (predvaritel'no  ochistiv  etu  stroku  s pomoshch'yu KEY
OFF).  Dlya otmeny avtomaticheskogo sdviga ekrana v strokah 24 i 25
nado  zavershat'  operator PRINT tochkoj s zapyatoj (chtoby  otmenit'
sdvig v poziciyah 24,80 i 25,80 nado ispol'zovat' pryamoe otobrazhe-
nie v pamyat' [4.3.1]).  Nizhe priveden primer risovaniya vertikal'-
noj cherty s pomoshch'yu odnogo  iz  simvolov  psevdografiki  v centre
ekrana.

100 FOR N = 1 TO 25     'povtor dlya kazhdoj stroki
110 LOCATE N,40         'ustanovka kursora v seredinu stroki
120 PRINT CHR$(186);    'pechataem vertikal'nuyu chertu
130 NEXT                'perehod k sleduyushchej stroke

Kogda  ispol'zuetsya  neskol'ko displejnyh  stranic,  to  operator
LOCATE dejstvuet na tekushchej aktivnoj stranice pamyati.  Esli stra-
nica, vyvodimaya v dannyj moment na monitor, ne aktivna, to  polo-
zhenie kursora na ekrane ne  menyaetsya.   Otmetim, chto Bejsik imeet
sobstvennuyu peremennuyu, hranyashchuyu tekushchee polozhenie kursora.  Esli
Vy podklyuchite assemblernuyu podprogrammu,  kotoraya izmenit polozhe-
nie kursora, to Bejsik proignoriruet novuyu poziciyu kursora, kogda
emu budet vozvrashcheno upravlenie.

   Srednij uroven'.

   Operacionnaya  sistema predostavlyaet dva sposoba pozicionirova-
niya kursora v absolyutnuyu poziciyu na  ekrane. Funkciya 2 preryvaniya
10H ustanavlivaet kursor, otnosyashchijsya k ukazannoj stranice  pamya-
ti. Stranicy numeruyutsya nachinaya s nulya i dlya monohromnogo displeya
nomer  stranicy  (nahodyashchijsya v BH) dolzhen vsegda byt' ravnym  0.
DH:DL soderzhat stroku  i  stolbec,  kotorye  tozhe numeruyutsya s 0.
Kursor  menyaet  svoe  polozhenie na ekrane tol'ko  esli  ustanovka
kursora otnositsya k tekushchej aktivnoj stranice.

;---ustanovka kursora v stroku 13, stolbec 39
   MOV  AH,2        ;nomer funkcii
   MOV  BH,0        ;nomer stranicy
   MOV  DH,13       ;stroka
   MOV  DL,39       ;stolbec
   INT  10H         ;pozicioniruem kursor


   Vtoroj metod pozicionirovaniya kursora  sostoit v ispol'zovanii
special'nogo  drajvera ustrojstva ANSI.SYS, kotoryj  dolzhen  byt'
zagruzhen pri starte  sistemy.  V  prilozhenii  D  dany neobhodimye
svedeniya.   Dlya vyvoda stroki, soderzhashchej informaciyu o  stroke  i
stolbce ispol'zuetsya funkciya 9 preryvaniya 21H.  Stroka nachinaetsya
s simvola Esc (ASCII 27), a zavershaetsya simvolom ogranichitelem $.
Format stroki  Esc[stroka,stolbecH$,  gde  stroka i stolbec nume-
ruyutsya  ot nulya, a Esc oboznachaet kod ASCII 27.  Naprimer, stroka
27,'10;60H$' ustanavlivaet kursor v stroku 10, stolbec 60.

   Hotya takoj metod kazhetsya  izlishne  slozhnym,  no on okazyvaetsya
ochen' udobnym pri vyvode ryada strok na ekran, tak kak  Esc-posle-
dovatel'nost' obrabatyvaetsya kak  odna iz strok nabora.  V dannom
primere tri stroki soobshcheniya razbrosany po vsemu ekranu.

;---v segmente dannyh
POSITION_1   DB   27,'[10;30H$'
STRING_1     DB   'There are two options:$'
POSITION_2   DB   27,'[13;32H$'
STRING_2     DB   '(1) Review part 1$'
POSITION_3   DB   27,'[15;32H$'
STRING_3     DB   '(2) Move on to part 2$'
;---pechat' strok
   MOV  AH,9           ;nomer funkcii vyvoda stroki
   LEA  DX,POSITION_1  ;1-ya stroka pozicionirovaniya kursora
   INT  21H            ;pozicioniruem kursor
   LEA  DX,STRING_1    ;1-ya tekstovaya stroka
   INT  21H            ;vyvod stroki
   LEA  DX,POSITION_2  ;i t.d.
   INT  21H            ;
   LEA  DX,STRING_2    ;
   INT  21H            ;
   LEA  DX,POSITION_3  ;
   INT  21H            ;
   LEA  DX,STRING_3    ;
   INT  21H            ;

   Nizkij uroven'.

   Registry 14 i 15 mikroshemy 6845 hranyat polozhenie kursora.  Vy
mozhete izmenit' ih znachenie i kursor peredvinetsya v sootvetstvuyu-
shchuyu  poziciyu  ekrana,  no preryvaniya vyvoda na ekran  DOS i  BIOS
budut ignorirovat' Vashu ustanovku  i vernut kursor v staroe polo-
zhenie.   |to  proishodit potomu, chto kazhdyj raz pri  vyzove  etih
preryvanij,  oni   vosstanavlivayut   registry  kursora, ispol'zuya
2-bajtnoe  znachenie,  hranyashcheesya v oblasti dannyh BIOS.   V  etoj
oblasti, nachinaya s adresa  0040:0050,  mogut nahodit'sya do vos'mi
takih  znachenij,  davaya tekushchee polozhenie kursora dlya  kazhdoj  iz
stranic displeya. Procedura nizkogo urovnya dolzhna modificirovat' i
eti znacheniya, chtoby izmenit' sostoyanie kursora polnost'yu.
   Poziciya kursora hranitsya v registrah 14 i 15 kak chislo ot 0 do
1999, chto sootvetstvuet 2000 (25*80) poziciyam ekrana. Ne sputajte
etu  sistemu numeracii s poziciyami videobufera ot 0 do 3999,  gde
kazhdyj simvol soprovozhdaetsya eshche  bajtom atributov (dlya polucheniya


ekvivalentnogo  ukazatelya na poziciyu kursora nado sdvinut' ukaza-
tel' videobufera na 1 bit vpravo).  Obrashchaem takzhe Vashe vnimanie,
na  to,  chto ne nado menyat' mestami starshij i  mladshij  bajty:  v
registre 14 - starshij, a 15 - mladshij.

;---v programme
   MOV  BL,24         ;stroka v BL (0-24)
   MOV  BH,79         ;stolbec v BH (0-79)
   CALL SET_CURSOR    ;vyzov procedury

;---procedura ustanovki kursora
SET_CURSOR  PROC
   ;poluchaem dostup k registru mladshego bajta
       MOV  DX,3B4H   ;port adresnogo registra 6845
       MOV  AL,15     ;vybiraem registr 15
       OUT  DX,AL     ;posylaem zapros
   ;vychislenie pozicii kursora
       MOV  AL,80     ;umnozhaem nomer stroki na 80
       MUL  BL        ;v AX - nomer stroki, umnozhennyj na 80
       MOV  BL,BH     ;perenosim nomer stolbca v BL
       SUB  BH,BH     ;rasprostranyaem BL na BX
       ADD  AX,BX     ;vychislyaem poziciyu kursora
   ;posylaem mladshij bajt rezul'tata
       INC  DX        ;adresuem upravlyayushchij registr
       OUT  DX,AL     ;posylaem mladshij bajt
   ;poluchaem dostup k registru starshego bajta
       MOV  AL,14     ;nomer trebuemogo registra
       DEC  DX        ;vosstanavlivaem port adresnogo registra
       OUT  DX,AL     ;posylaem zapros
   ;posylaem starshij bajt rezul'tata
       INC  DX        ;adresuem upravlyayushchij registr
       MOV  AL,AH     ;pomeshchaem starshij bajt v AL
       OUT  DX,AL     ;posylaem starshij bajt
       RET
SET_CURSOR    ENDP





   Inogda byvaet poleznym sdvinut' kursor otnositel'no ego predy-
dushchej  pozicii:  na stroku vverh, na tri stolbca  vpravo, i  t.d.
Dostatochno prosto ispol'zovat'  dlya etoj celi uzhe opisannoe abso-
lyutnoe pozicionirovanie kursora.  No dlya udobstva MS DOS  predos-
tavlyaet nekotorye vozmozhnosti otnositel'nogo peremeshcheniya kursora.

   Srednij uroven'.

   Funkcii   otnositel'nogo   peremeshcheniya   kursora   vypolnyayutsya
Esc-posledovatel'nostyami.  |to stroki, kotorye vyvodyatsya na ekran
s pomoshch'yu funkcii 9 preryvaniya 21H. V prilozhenii D dany osnovy ih
ispol'zovaniya.   Takie posledovatel'nosti interpretiruyutsya MS DOS
kak komandy  peremeshcheniya  kursora,  a  ne  vyvod simvolov stroki.
Stroka nachinaetsya s simvola Esc (ASCII 27), zatem idet simvol  [,
a simvol $ otmechaet konec  stroki.   Sama stroka sostoit iz chisla
pozicij,  na kotoroe nado sdvinut'sya, i koda napravleniya.   CHtoby
sdvinut'sya na 3 pozicii:

         vverh           3A
         vniz            3B
         vpravo          3C
         vlevo           3D

CHisla zapisyvayutsya kak kody ASCII. Ne preobrazujte, naprimer, 33C
(33 probela vpravo) v 33,'C'; dolzhno byt' '33C'.  V nizhepriveden-
nom primere cifry  1-8  pomeshchayutsya  cherez  opredelennye intervaly
poperek ekrana, kak metki stolbcov dannyh.  Promezhutki mezhdu cif-
rami  generiruyutsya  Esc-posledovatel'nostyami,   kotorye  sdvigayut
kursor vpravo posle vyvoda kazhdoj cifry.

;---v segmente dannyh
CURSOR_RIGHT   DB   27,'[9C$'

;---ustanovka nachal'noj pozicii kursora
   MOV  BH,0             ;noier stranicy
   MOV  DH,1             ;stroka
   MOV  DL,5             ;stolbec
   MOV  AH,2             ;funkciya ustanovki kursora
   INT  10H              ;ustanovka kursora
;---vyvod cifr
   LEA  BX,CURSOR_RIGHT  ;BX budet obmenivat'sya s DX
   MOV  CX,8             ;chislo cifr dlya vyvoda
   MOV  DL,'0'           ;nachinaem s 0
NEXT_NUMBER:   MOV  AH,2 ;funkciya DOS dlya vyvoda simvola
   INT  21H              ;vyvodim simvol
   INC  DL               ;perehodim k sleduyushchemu kodu ASCII
   XCHG DX,BX            ;pomeshchaem ukazatel' na stroku v DX
   MOV  AH,9             ;funkciya vyvoda stroki
   INT  21H              ;sdvigaem kursor na 9 pozicij vpravo
   XCHG DX,BX            ;vozvrashchaem v DX kod ASCII
   LOOP NEXT_NUMBER      ;perehodim k sleduyushchej cifre


   Imeetsya takzhe para Esc-posledovatel'nostej, kotorye  upravlyayut
perenosom kursora na  sleduyushchuyu  stroku  pri  dostizhenii im konca
tekushchej  stroki.   Kogda ustanavlivaetsya otsutstvie perenosa,  to
lishnie simvoly pri  vyvode   otbrasyvayutsya.  Stroka,  zapreshchayushchaya
perenos  - Esc [=7h (ili kak dannye, 27,'[=7h').  Dlya vozvrata  k
rezhimu avtomaticheskogo perenosa na  sleduyushchuyu stroku ispol'zuetsya
stroka Esc [=7l (27,'[=7l').





   Kursor generiruetsya mikroshemoj 6845.  On funkcioniruet sover-
shenno nezavisimo ot videopamyati. |to znachit, chto pri pryamoj adre-
sacii  v  pamyat' displeya [4.3.1] programmnoe  obespechenie  dolzhno
koordinirovat' peremeshcheniya  kursora  s  vstavkoj novogo simvola v
bufer.  Otmetim, chto mikroshema 6845 ne mozhet ni sozdavat' nemer-
cayushchij kursor, ni izmenit' chastotu ego mercaniya.  V [4.2.6] poka-
zano kak skonstruirovat' drugie "iskusstvennye" tipy kursora.

   Vysokij uroven'.

   Interpretator  Bejsika avtomaticheski vyklyuchaet kursor pri  za-
puske programmy.  Kursor  poyavlyaetsya, kogda ispol'zuetsya operator
INPUT,  no ne v drugih sluchayah.  Esli Vashej  programme  neobhodim
kursor, skazhem dlya  procedury  INKEY$,  to on dolzhen byt' vklyuchen
ustanovkoj  tret'ego parametra operatora LOCATE v 1 (0 snova vyk-
lyuchit ego). Napominaem, chto pervye dva parametra operatora LOCATE
ustanavlivayut stroku i stolbec, v kotoryh dolzhen vyvodit'sya  kur-
sor.

   100 LOCATE 15,40,1  ;vklyuchit' kursor, ego poziciya 15,40
ili
   100 LOCATE ,,1      ;vklyuchit' kursor v tekushchej pozicii
i
   100 LOCATE ,,0      ;snova vyklyuchit' kursor

Kursor budet  ostavat'sya  pri  posleduyushchih  poyavleniyah  operatora
LOCATE bez ustanovki kazhdyj raz tret'ego parametra.  Odnako  nado
otmetit', chto  operatory  INPUT  i  INPUT$  vyklyuchat ego posle ih
vypolneniya.

   Srednij uroven'.

   Assemblernye  programmy  ostavlyayut kursor vklyuchennym,  do  teh
por, poka im ne ukazano obratnoe. Operacionnaya sistema ne predos-
tavlyaet  special'nyh  sredstv  vyklyucheniya kursora, no  eto  legko
sdelat'.  Nado prosto pozicionirovat' kursor za predely ekrana, s
pomoshch'yu  funkcii 2 preryvaniya 10H ustanovit' ego v pervuyu poziciyu
26-j stroki.  Pomnite, chto  koordinaty otschityvayutsya ot nulya, tak
chto etoj pozicii sootvetstvuyut koordinaty 25,0.

   MOV  BH,0    ;nomer stranicy (vsegda 0 dlya monohromnogo)
   MOV  DH,25   ;stroka
   MOV  DL,0    ;stolbec
   MOV  AH,2    ;nomer funkcii
   INT  10H     ;ustanavlivaem kursor za predely ekrana


   Nizkij uroven'.

   Bit  6  registra 10 mikroshemy 6845 [4.1.1] vyklyuchaet  kursor,
kogda on ustanovlen v 1, i vklyuchaet  ego, kogda sbroshen v 0. |tot
registr  soderzhit takzhe znachenie "nachal'noj stroki" dlya  kursora,
kotoroe vmeste so znacheniem "konechnoj  stroki" opredelyaet tolshchinu
kursora  [4.2.4].  Poskol'ku tip kursora ne imeet znacheniya, kogda
kursor vyklyuchen, to nado prosto  pomestit'  v registr 10 znachenie
32, chtoby ustanovit' bit 6.  CHtoby vosstanovit' kursor Vy  dolzhny
takzhe vernut' znachenie "nachal'noj  stroki" kursora.  Dlya normal'-
nogo  kursora eto znachenie ravno 11.  Znachenie "konechnoj  stroki"
pri etih procedurah ne menyaetsya,  poskol'ku ono hranitsya v drugom
registre.

;---vyklyuchenie kursora
   MOV  DX,3B4H     ;nomer porta adresnogo registra 6845
   MOV  AL,10       ;vybor registra 10
   OUT  DX,AL       ;posylaem zapros
   INC  DX          ;dostup k registru cherez sleduyushchij port
   MOV  AL,32       ;ustanavlivaem bit 6 dlya vyklyucheniya kursora
   OUT  DX,AL       ;vyklyuchaem kursor
;---obratnoe vklyuchenie kursora
   MOV  AL,11       ;znachenie "nachal'noj stroki"
   OUT  DX,AL       ;vklyuchaem kursor





   Kursor mozhet menyat'sya po tolshchine ot tonkoj linii do maksimal'-
nogo razmera, otvodimogo  pod  simvol.   On  stroitsya iz korotkih
gorizontal'nyh otrezkov, verhnij iz kotoryh nazyvaetsya "nachal'noj
strokoj" kursora, a nizhnij - "konechnoj strokoj". Dlya monohromnogo
displeya  pod kazhdyj simvol otvoditsya 14 strok, pronumerovannyh ot
0 do 13, nachinaya sverhu. Promezhutki mezhdu simvolami obespechivayut-
sya dvumya verhnimi strokami i tremya nizhnimi.  Bol'shinstvo simvolov
raspologayutsya v strokah  2-10,  hotya  hvostiki nekotoryh simvolov
dostigayut  linij  12 i 13, v to vremya kak podcherkivanie  zanimaet
odnu dvenadcatuyu stroku.
   Na 200-strochnom cvetnom displee dlya kazhdogo simvola  otvoditsya
tol'ko 8 strok, a simvol  risuetsya  v verhnih semi strokah. |ti 8
strok  pronumerovany ot 0 do 7, nachinaya sverhu, i normal'nyj kur-
sor formiruetsya odnoj strokoj 7. (Otmetim, chto na cvetnom displee
net  podcherkivaniya,  poskol'ku  ispol'zovanie  dlya  podcherkivaniya
stroki 7 privelo by k tomu, chto  simvoly  slivalis' by s raspolo-
zhennymi pod nimi.) Cvetnoj displej vysokogo razresheniya ispol'zuet
14-strochnyj monohromnyj variant, kogda on rabotaet v rezhime vyso-
kogo razresheniya, a kogda on rabotaet v odnom iz cvetnyh grafiches-
kih rezhimov, to on ispol'zuet 8-strochnyj rezhim.
   Kursor mozhet byt' sformirovan  lyuboj  kombinaciej  prilegayushchih
otrezkov. Dlya monohromnogo displeya on zanimaet vse otvedennoe pod
simvol mesto, kogda "nachal'naya stroka" ravna 0, a "konechnaya stro-
ka" ravna 13 (dlya graficheskogo displeya nado ispol'zovat' znachenie
"konechnoj stroki" ravnoe 7).  Esli znacheniya "nachal'noj" i "konech-
noj"  stroki sovpadayut, to voznikaet odnostrochnyj  kursor.   Esli
nomer "konechnoj stroki" men'she  chem "nachal'noj" to voznikaet kur-
sor, sostoyashchij iz dvuh chastej, tak kak proishodit perenos v verh-
nie stroki. Naprimer, esli "nachal'naya stroka" ravna 12, a "konech-
naya"  - 1, to snachala zapolnyaetsya stroka 12, zatem 13, zatem 0 i,
nakonec, 1.  Kursor pri  etom  prinimaet  formu dvuh parallel'nyh
linij,  ukazyvayushchih  verhnyuyu  i nizhnyuyu granicy ryada,  kotoryj  on
zanimaet.
   BIOS hranit 2-bajtnuyu peremennuyu  po adresu 0040:0060, kotoraya
soderzhit tekushchie znacheniya "nachal'noj" i "konechnoj" strok.  Pervyj
bajt soderzhit znachenie "konechnoj stroki", a vtoroj - "nachal'noj".

   Vysokij uroven'.

   V Bejsike  operator  LOCATE  mozhet  ne  tol'ko pozicionirovat'
kursor  i vklyuchat' ili vyklyuchat' ego, no i upravlyat' ego  formoj.
Parmetry, ustanavlivayushchie  "nachal'nuyu"  i "konechnuyu" stroki - eto
4-e  i  5-e chislo, sleduyushchie za slovom LOCATE.  Drugie  parametry
mogut byt' opushcheny,  esli  prisutstvuyut  razdelyayushchie  ih zapyatye.
Takim obrazom, chtoby sozdat' tolstyj kursor, zanimayushchij stroki so
2 po 12, nado zapisat' LOCATE ,,,2,12. Otmetim, chto Bejsik obychno
vyklyuchaet kursor, kogda nachinaet vypolnenie programmy.  Kak vklyu-
chit' ego obratno sm. v [4.2.3].


   Srednij uroven'.

   Funkciya 1 preryvaniya  BIOS  10H  ustanavlivaet  "nachal'nuyu"  i
"konechnuyu" stroki kursora.  V CH dolzhna byt' ukazana "nachal'naya",
a v CL - "konechnaya" stroka.

;---ustanovka "nachal'noj" i "konechnoj" strok kursora
   MOV  AH,1      ;nomer funkcii
   MOV  CH,0      ;nachat' kursor v verhnej stroke
   MOV  CL,7      ;okonchit' kursor v vos'moj stroke
   INT  10H       ;
   Nizkij uroven'.

   Registry 10 i 11  kontrollera  displeya  6845 soderzhat znacheniya
"nachal'noj" i "konechnoj" stroki, sootvetstvenno.  Dostup k  oboim
registram osushchestvlyaetsya cherez port 3B5H dlya monohromnogo adapto-
ra  i 3D5H - dlya cvetnogo alaptora i PCjr.   Predvaritel'no  nado
poslat' nomer  trebuemogo  registra  v  adresnyj registr, imeyushchij
adres porta 3B4H (sm.  [4.1.1]).  Znacheniya zanimayut mladshij konec
kazhdogo registra.  Odnako registr "nachal'noj" stroki (#10) bitami
5  i 6 indiciruet takzhe dolzhen li vyvodit'sya  kursor.   Poskol'ku
kursor vyvoditsya, kogda  oba  etih  bita  sbrosheny v 0, to prosto
pomestiv v registr nomer "nachal'noj" stroki my ustanovim eti bity
v 0. Ostal'nye bity etogo registra ne ispol'zuyutsya.

;---ustanovka "nachal'noj" stroki
   MOV  DX,3B4H     ;dostup k adresnomu registru 6845
   MOV  AL,10       ;vybor registra 6845
   OUT  DX,AL       ;posylka zaprosa
   MOV  AL,0        ;nomer "nachal'noj stroki" 0
   INC  DX          ;perehodim k upravlyayushchemu registru
   OUT  DX,AL       ;posylaem nomer "nachal'noj stroki"
;---ustanovka "konechnoj stroki"
   MOV  AL,11       ;vybiraem registr 11
   DEC  DX          ;vozvrashchaemsya k adresnomu registru
   OUT  DX,AL       ;posylaem zapros
   MOV  AL,7        ;nomer "konechnoj stroki" 7
   INC  DX          ;perehodim k upravlyayushchemu registru
   OUT  DX,AL       ;posylaem nomer "konechnoj stroki"





   Programmy inogda chitayut i sohranyayut tekushchee polozhenie kursora,
s tem chtoby  mozhno  bylo  vremenno  perevesti  kursor v komandnuyu
stroku, a zatem vernut' ego v ishodnuyu poziciyu.  Tekushchaya  poziciya
kursora dlya kazhdoj iz vplot' do vos'mi stranic hranitsya v oblasti
dannyh BIOS.  Imeetsya vosem' 2-bajtnyh peremennyh,  razmeshchayushchihsya
nachinaya s adresa 0040:0050. Pervaya poziciya sootvetstvuet stranice
0,  vtoraya  - stranice 1 i t.d.  Mladshij bajt  kazhdoj  peremennoj
soderzhit nomer stolbca, a  mladshij  -  nomer stroki. Kak stolbcy,
tak i stroki numeruyutsya, nachinaya s nulya.

   Vysokij uroven'.

   V Bejsike operator CRSLIN vozvrashchaet stroku, a POS -  stolbec.
Operator POS dolzhen byt'  snabzhen  fiktivnym  argumentom, t.e. on
vsegda dolzhen zapisyvat'sya v vide POS(0). V dannom primere kursor
perevoditsya v nizhnyuyu stroku ekrana,  a zatem vozvrashchaetsya na mes-
to.   Otmetim, chto kursor vozvrashchaetsya na mesto posle  vypolneniya
operatora INPUT [4.2.3].

100 ROW = CRSLIN        'poluchaem stroku kursora
110 COL = POS(0)        'poluchaem stolbec kursora
120 LOCATE 25,1         'perevodim kursor v komandnuyu stroku
130 INPUT "Enter file name", F$  'zapros na vvod
140 LOCATE ROW,COL,1    'vosstanavlivaem poziciyu kursora

   Srednij uroven'.

   Funkciya  3  preryvaniya 10H vozvrashchaet stroku kursora v  DH,  a
stolbec - v DL. Na  vhode  nado  pomestit'  v  BH  nomer stranicy
(vsegda 0 dlya monohromnogo displeya).

;---opredelenie pozicii kursora
   MOV  AH,3     ;nomer funkcii
   MOV  BH,0     ;stranica 0
   INT  10H      ;stroka:stolbec v DH:DL

   MS DOS predostavlyaet dve Esc-posledovatel'nosti dlya sohraneniya
i vosstanovleniya pozicii kursora. |to special'nye stroki, kotorye
esli ih "vyvesti" na terminal upravlyayut monitorom. Osnovy ispol'-
zovaniya etih posledovatel'nostej opisany v prilozhenii D. Posledo-
vatel'nost' dlya zapominaniya pozicii kursora - Esc[s, a dlya  voss-
tanovleniya - Esc[u. Net nuzhdy zapominat' koordinaty v peremennoj.

;---v segmente dannyh
SAVE_CURSOR     DB   27,'[s$'
RESTORE_CURSOR  DB   27,'[u$'

;---sohranenie kursora
   LEA  DX,SAVE_CURSOR   ;adres nachala stroki v DX
   MOV  AH,9             ;nomer funkcii vyvoda stroki
   INT  21H              ;sohranyaem poziciyu kursora


;---vosstanovlenie kursora
   LEA  DX,RESTORE_CURSOR   ;adres nachala stroki v DX
   MOV  AH,9             ;nomer funkcii vyvoda stroki
   INT  21H              ;vosstanavlivaem poziciyu kursora

   Nizkij uroven'.

   Registry 14 i 15 mikroshemy 6845 hranyat tekushchuyu poziciyu kurso-
ra, kak ob®yasnyalos' v [4.1.1].  Starshij bajt hranitsya v  registre
14. Dva bajta hranyat chisla ot  0  do  1999 v rezhime 80 simvolov v
stroke i ot 0 do 999 v rezhime 40 simvolov.  Vam neobhodimo  pere-
vesti poluchaemoe chislo v koordinaty stroki i stolbca.  Vy  mozhete
prochitat' eto znachenie,  chtoby  uznat'  tekushchee  poziciyu vidimogo
kursora  na ekrane.  No zapominanie etogo znacheniya i  posleduyushchee
vosstanovlenie ego v registrah ne obyazatel'no privedet k vozvratu
kursora  v  predydushchuyu poziciyu, osobenno esli Vasha programma  is-
pol'zuet lyubuyu iz obychnyh funkcij raboty s ekranom, predostavlyae-
myh operacionnoj sistemoj. |to proishodit potomu, chto BIOS hranit
polozhenie kursora v svoih  peremennyh,  dlya togo chtoby imet' voz-
mozhnost' upravlyat' stranicami displeya [4.5.3].  Posle togo kak Vy
vosstanovite registry 14 i 15 kursor peremestitsya v sootvetstvuyu-
shchuyu  poziciyu, no pri sleduyushchem vyzove preryvaniya vyvoda na  ekran
kursor vernetsya nazad k toj  pozicii,  v  kotoroj on dolzhen naho-
dit'sya soglasno znacheniyam peremennyh BIOS.





   Vse  preryvaniya operacionnoj sistemy, svyazannye s  vyvodom  na
ekran, ispol'zuyut  kursor.  Vy  mozhete  izmenit'  formu kursora s
pomoshch'yu tehniki pokazannoj v [4.2.4] ili sdelat' kursor nevidimym
[4.2.3].  Vozmozhny  al'ternativnye  tipy  kursora, kogda vyvod na
ekran  osushchestvlyaetsya s pomoshch'yu metoda pryamogo otobrazheniya v  pa-
myat' [4.3.1].  Pri etom  "istinnyj" kursor vyklyuchaetsya, poskol'ku
on  ne budet adresovat' simvoly v opredelennuyu poziciyu videobufe-
ra.  Vmesto etogo  sozdaetsya  "fal'shivyj"  kursor s pomoshch'yu bajta
atributov.
   Naibolee effektivnym metodom yavlyaetsya ustanovka atributa vyvo-
da v negative dlya simvola, na kotoryj ukazyvaet kursor.  Dlya cher-
no-belogo  ekrana  dlya etogo atributa  sleduet  ispol'zovat'  kod
ASCII 112. Drugoj sposob - zastavit' simvol, na kotoryj ukazyvaet
kursor migat'.  V etom sluchae nado prosto dobavit' 128 k tekushchemu
znacheniyu atributa,  chtoby  simvol  nachal  migat',  i vychest' 128,
chtoby prekratit' miganie.  Tretij sposob - ustanovit' dlya simvola
rezhim podcherkivaniya (ispol'zuya kod ASCII 1).  I, nakonec, v prog-
rammah  ispol'zuyushchih komandnuyu stroku mozhno  rassmotret'  vozmozh-
nost'  ispol'zovaniya  special'nogo  graficheskogo simvola, kotoryj
sleduet za poslednim simvolom komandnoj stroki, takogo kak strel-
ki vyvodimye kodami ASCII 17 ili 27. Otmetim, chto kogda programma
poluchaet vvod v neskol'kih rezhimah, to Vy mozhete pomoch' identifi-
cirovat' tekushchij rezhim za schet osobogo tipa kursora.

   Vysokij uroven'.

   V dannom primere kursor  formiruetsya  za schet vyvoda simvola v
pozicii  kursora  v negative.  Peremennaya  CURSORPOSITION  hranit
smeshchenie simvola, na kotoryj ukazyvaet kursor v videobufere.  |to
chetnoe  chislo v intervale ot 0 do 3998.  Pribavlenie k etoj pere-
mennoj 1 daet poziciyu bajta atributov  dlya etogo simvola i pomes-
tiv  tuda 112 my obespechim vyvod etogo simvola v negative.  Pere-
mennaya FORMERATTRIBUTE  hranit  obychnye  atributy  simvola, s tem
chtoby mozhno bylo vosstanovit' ih posle togo kak kursor sdvinetsya.

500 '''procedura analiza postupayushchih rasshirennyh kodov
 .
560 IF EXTENDEDCODE = 77 THEN GOSUB 5000  'kursor vpravo

5000 '''procedura sdvigayushchaya kursor vpravo na odnu poziciyu
5010 POKE CURSORPOSITION+1,FORMERATTRIBUTE  'vosst. atribut
5020 CURSORPOSITION = CURSORPOSITION+2      'novaya poziciya
5030 FORMERATTRIBUTE = PEEK(CURSORPOSITION+1)  'sohr. atribut
5040 POKE CURSORPOSITION+1,112              'vklyuchaem negativ
5050 RETURN                                 'vse sdelano


   Nizkij uroven'.

   Zdes' tot zhe samyj primer realizovan na assemblere:

;---procedura peremeshcheniya kursora na odnu poziciyu vpravo
CURSOR_RIGHT:  MOV  BX,CURSORPOSITION  ;poluchenie pozicii
   INC  BX                  ;ukazyvaem na atribut simvola
   MOV  AL,FORMERATTRIBUTE  ;berem sohranennyj atribut
   MOV  ES:[BX],AL          ;vosstanavlivaem ego
   INC  BX                  ;ukazyvaem na sleduyushchij simvol
   MOV  CURSORPOSITION,BX   ;sohranyaem ego smeshchenie
   MOV  AL,ES:[BX]+1        ;poluchaem atribut novogo simvola
   MOV  FORMERATTRIBUTE,AL  ;sohranyaem ego
   MOV  AL,112              ;pomeshchaem atribut vyvoda v negative
   MOV  ES:[BX]+1,AL        ;zasylaem ego dlya sleduyushchego simvola




   Imeetsya  mnogo sposobov vyvoda simvolov na  ekran.   Nekotorye
prosto pomeshchayut odin simvol,  belyj  na chernom, v tekushchuyu poziciyu
kursora.  Drugie metody bolee slozhny, no dayut bol'she vozmozhnostej
upravleniya razmeshcheniem simvolov, a takzhe ih atributami i cvetami.
Nekotorye  procedury vyvodyat na ekran celye stroki.   No v  lyubom
sluchae, osnovnoj operaciej,  na  kotoroj  osnovan vyvod, yavlyaetsya
pomeshchenie  koda ASCII vyvodimogo simvola v ukazannuyu poziciyu  vi-
deobufera; pri etom mozhet takzhe  zapisyvat'sya  i bajt atributov v
sleduyushchij adres pamyati.
   Vashi  programmy mogut pomeshchat' eti kody neposredstvenno v  bu-
fer, etot metod nazyvaetsya  otobrazheniem  v pamyat'. Otobrazhenie v
pamyat',  kak pravilo, trebuet bol'she usilij pri  programmirovanii
dlya vypolneniya zadannoj  funkcii,  chem pri ispol'zovanii procedur
operacionnoj  sistemy,  no v rezul'tate  poluchaem  bolee  bystryj
vyvod na ekran. IBM ne rekomenduet ispol'zovat' etot metod vyvoda
na ekran, poskol'ku budushchie izmeneniya apparatury mogut privesti k
tomu, chto programmy budut rabotat' neverno. No na samom dele poka
vse  novye razrabotki IBM sleduyut odnoj i toj zhe sheme adresacii,
na kotoroj osnovano otobrazhenie v pamyat'.





   Vse procedury dlya  vyvoda  simvola  na  ekran  v BIOS i DOS (a
takzhe  v  Bejsike) pomeshchayut simvol v tekushchuyu  poziciyu  kursora  i
avtomaticheski peredvigayut kursor na odnu poziciyu vpravo.  Vse oni
perenosyat vyvod na sleduyushchuyu stroku pri dostizhenii konca  stroki,
esli ne sdelano special'nyh  ukazanij  otbrasyvat' vse simvoly za
80-m stolbcom [4.2.2]. Vazhnoe otlichie mezhdu otdel'nymi procedura-
mi sostoit v tom, chto nekotorye  vmeste  s simvolom pishut takzhe i
ego atributy, a nekotorye etogo ne delayut.
   Kak  v yazykah vysokogo, tak i v yazykah nizkogo urovnya, simvoly
mogut vyvodit'sya na  ekran  bez  ispol'zovaniya  obychnyh  operacij
pechati.   Vmesto etogo ispol'zuetsya pryamoe otobrazhenie v  pamyat',
pri kotorom kody simvolov i ih atributy pryamo zasylayutsya v yachejki
pamyati videobufera, sootvetstvuyushchie opredelennoj pozicii  kursora
na ekrane. Bufer nachinaetsya s  adresa  B000:0000 dlya monohromnogo
adaptora i s adresa B800:0000 - dlya cvetnogo graficheskogo adapto-
ra i PCjr.  EGA ispol'zuet te zhe samye adresa v analogichnyh rezhi-
mah ekrana.  Pozicii s chetnymi nomerami (nachinaya s nulya) soderzhat
kody ASCII simvolov, a pozicii s nechetnymi nomerami - bajty atri-
butov.  Na ris. 4-2 pokazan uchastok pamyati videobufera.  Pri etih
operaciyah poziciya kursora ne  menyaetsya  i  on mozhet byt' vyklyuchen
pri  zhelanii  [4.2.3].  Vmesto kursora nado  hranit'  peremennye,
sluzhashchie ukazatelyami na tekushchuyu poziciyu.

   Vysokij uroven'.

   Bejsik vyvodit kak  otdel'nye  simvoly,  tak i celye stroki, s
pomoshch'yu  odnih i teh zhe operatorov PRINT i WRITE.   Kak  pravilo,
ispol'zuetsya  PRINT; WRITE - eto odin iz variantov so special'ny-
mi, redko ispol'zuemymi formatami vyvoda. PRINT rabotaet s danny-
mi treh vidov.  On vyvodit soderzhimoe kak strokovyh, tak i chislo-
vyh peremennyh, naprimer, PRINT S$ ili PRINT X.  On vyvodit takzhe
simvoly, vstavlennye (v kavychkah) vnutr' samogo operatora  PRINT,
naprimer, PRINT "This words are printed". On vyvodit takzhe simvo-
ly,  sootvetstvuyushchie  kodam ASCII, vklyuchennym v operator PRINT  v
vide operatorov CHR$, naprimer,  PRINT  CHR$(65),  chto privodit k
vyvodu na ekran simvola A (kod ASCII #65).
   V  odnom  operatore PRINT mogut vyvodit'sya mnogo  dannyh,  pri
etom vse tri formy dannyh mogut byt' peremeshany. Otdel'nye dannye
otdelyayutsya zapyatoj ili tochkoj s zapyatoj. Zapyataya privodit k tomu,
chto sleduyushchie dannye budut vyvodit'sya  so sleduyushchej pozicii tabu-
lyacii dannoj stroki.  Tochka s zapyatoj privodit k tomu, chto dannye
pechatayutsya na ekrane podryad, ne  razdelennye  probelami (otmetim,
chto PRINT vstavlyaet probel pered vyvodom lyuboj chislovoj  peremen-
noj, a WRITE ne delaet etogo). Obychno operator PRINT avtomatiches-
ki  delaet perevod na novuyu stroku pri zavershenii, takim  obrazom
sleduyushchij  takoj  operator  nachnet  vyvod  s novoj stroki ekrana.
CHtoby perenos na novuyu stroku ne proishodil nado v konce operato-
ra PRINT postavit' tochku s zapyatoj, naprimer, PRINT S$;.
   Dlya ustanovki pozicii kursora  pered  vyvodom ispol'zuetsya op-
erator LOCATE. Bez operatora LOCATE PRINT vsegda nachinaet vyvod s
pervoj pozicii stroki, v kotoroj nahoditsya kursor. Posledovatel'-
nye  operatory  PRINT zapolnyayut ekran do teh por, poka  ne  budet


zapisana 24-ya stroka, posle  chego  ekran  sdvigaetsya vverh, s tem
chtoby  sleduyushchij operator PRINT snova vyvodil 24-yu stroku.  PRINT
mozhet vyvodit' v 25-j  stroke  tol'ko  pri  pomoshchi  LOCATE; i eto
takzhe privodit k avtomaticheskomu sdvigu ekrana vverh.  CHtoby zap-
retit' sdvig nado okonchit' operator PRINT tochkoj s zapyatoj. Odna-
ko  etot  metod ne srabotaet v poslednih poziciyah strok 24 i  25.
Dlya zapolneniya etih pozicij bez sdviga ekrana Vy dolzhny ispol'zo-
vat' otobrazhenie v pamyat', kak pokazano nizhe.
   Vy mozhete vklyuchat' upravlyayushchie simvoly [7.1.9] vnutr' operato-
ra PRINT dlya togo chtoby  realizovat'  peremeshcheniya  kursora vnutri
stroki.  Naprimer, esli Vy pomestite v stroku CHR$(13), to v etoj
tochke budet sdelan vozvrat karetki.   Esli Vy vyvedete operatorom
PRINT stroku "One"+CHR$(13)+"Two"+CHR$(13)+"Three", to v  rezul'-
tate kazhdoe slovo budet  vyvodit'sya  s  novoj stroki.  Kody ASCII
28-31  sdvigayut  kursor na odnu  poziciyu  sootvetstvenno  vpravo,
vlevo, vverh i vniz. Operator PRINT ne soderzhashchij dannyh privodit
k  vyvodu  vozvrata karetki i, takim obrazom, sleduyushchij  operator
PRINT budet vyvodit' na stroke cherez odnu.
   Pryamoe otobrazhenie v pamyat'  sushchestvenno  uvelichivaet skorost'
vyvoda na ekran v Bejsike. Ono osobenno polezno pri konstruirova-
nii tablichnogo vyvoda, kogda formy mogut dostigat' pravogo nizhne-
go  ugla ekrana.  Snachala nado ustanovit' ukazatel'  segmenta  na
&HB000, a zatem  ispol'zovat'  operator  POKE  dlya zasylki bajtov
pamyati.  Prilegayushchie po gorizontali simvoly otstoyat drug ot druga
na dva bajta, razdelyaemye  bajtom  atributov.   Dlya 80-simvol'nyh
ekranov prilegayushchie po vertikali simvoly otstoyat na 160 bajt drug
ot druga (2 bajta dlya kazhdogo  simvola  i atributov). V sleduyushchih
dvuh  primerah  vdol'  granicy ekrana risuetsya  ramka,  ispol'zuya
simvoly psevdografiki.  V pervom primere chashche ispol'zuetsya opera-
tor  PRINT, a vo vtorom ispol'zuetsya isklyuchitel'no pryamoe otobra-
zhenie v pamyat'. Otmetim, chto i v pervom sluchae prihoditsya ispol'-
zovat' pryamoe otobrazhenie v pamyat' v poslednih stolbcah strok  24
i 25, chtoby izbezhat' sdviga ekrana.

   Ispol'zovanie PRINT:

 10 CLS: KEY OFF              'ochistka ekrana
 20 DEF SEG = &HB000          'ukazyvaem na videobufer
 30 LOCATE 1,1: PRINT CHR$(201)   'levyj verhnij ugol
 40 LOCATE 1,80: PRINT CHR$(187)  'pravyj verhnij ugol
 50 LOCATE 1,24: PRINT CHR$(186)  '
 60 LOCATE 1,25: PRINT CHR$(200)  '
 70 POKE 3838,186                 'poziciya 80 stroki 24
 80 POKE 3998,188                 'poziciya 80 stroki 25
 90 FOR N=2 TO 79                 'gorizontal'nye linii
100 LOCATE 1,N: PRINT CHR$(205);: LOCATE 25,N: PRINT CHR$(205)
110 NEXT                          '
120 FOR N=2 TO 23                 'vertikal'nye linii
130 LOCATE N,1: PRINT CHR$(186): LOCATE N,80: PRINT CHR$(186)
140 NEXT


   Ispol'zovanie pryamogo otobrazheniya v pamyat':

 10 CLS: KEY OFF               'ochistka ekrana
 20 DEF SEG = &HB000           'bufer monohromnogo displeya
 30 POKE 0,201                 'levyj verhnij ugol
 40 POKE 158,187               'pravyj verhnij ugol
 50 POKE 3840,200              'levyj nizhnij ugol
 60 POKE 3998,188              'pravyj nizhnij ugol
 70 FOR N=2 TO 156 STEP 2      'gorizontal'nye pryamye
 80 POKE N,205: POKE N+3840,205  'kak verhnyaya, tak i nizhnyaya
 90 NEXT
100 FOR N=160 TO 3680 STEP 160 'vertikal'nye pryamye
110 POKE N,186: POKE N+158,186 'pravaya i levaya
120 NEXT

   Srednij uroven'.

   Operacionnaya  sistema  predostavlyaet shest' procedur vyvoda  na
ekran - tri v BIOS i tri v DOS.   Oni  otlichayutsya glavnym obrazom
tem, peredvigaetsya kursor ili net, posle vyvoda simvola, vyzyvayut
li oni sdvig ekrana, pozvolyayut  li  oni  ustanavlivat' atributy i
cveta simvolov, a takzhe kakie upravlyayushchie kody oni interpretiruyut
(nekotorye  rassmatrivayut  simvol  BackSpace,  prosto kak obychnyj
simvol, a nekotorye dejstvitel'no sdvigayut kursor na odnu poziciyu
nazad). |ti shest' procedur sleduyushchie:

   Preryvanie 10H:

   funkciya   9     vyvod simvola s atributami
             A     vyvod simvola bez atributov
             E     "teletajpnaya" procedura (kak na printer)

   Preryvanie 21H:

   funkciya   2     vyvod simvola bez atributov
             6     vyvod simvola bez atributov
             9     vyvod stroki simvolov

   Funkcii 9 i A preryvaniya 10H  voobshche  ne interpretiruyut uprav-
lyayushchie  simvoly.   Funkcii DOS interpretiruyut  upravlyayushchie  kody,
privedennye v sleduyushchej tablice. Funkciya E preryvaniya 10H interp-
retiruet vse kody tablicy, krome ASCII 9.

   ASCII   7     zvonok
   ASCII   8     vozvrat na shag (BackSpace)
   ASCII   9     tabulyaciya
   ASCII  10     perevod stroki
   ASCII  13     vozvrat karetki

   Pervye  dve funkcii preryvaniya 10H ne peredvigayut kursor posle
vyvoda simvola.  Funkciya  9  etogo  preryvaniya vyvodit na ekran s
ukazaniem  atributov, a funkciya A - bez ukazaniya, pri etom sohra-
nyaetsya tekushchee znachenie  bajta  atributov  dlya  etogo simvola. AL
dolzhen soderzhat' vyvodimyj simvol, a BL - atributy. Nomer strani-
cy displeya soderzhitsya v BH. On dolzhen ukazyvat'sya dazhe dlya monoh-


romnogo  displeya, kotoryj imeet tol'ko odnu stranicu pamyati disp-
leya. V etom sluchae dolzhna byt' ustanovlena pervaya stranica, koto-
roj sootvetstvuet nomer 0. Osoboe svojstvo etih dvuh funkcij BIOS
sostoit v tom, chto simvol vyvoditsya takoe chislo raz, kakoe ukaza-
no v CX. Obychno ukazyvayut CX ravnym 1, no eti funkcii mogut legko
vyvodit' celye  stroki  simvolov,  esli  ukazat' bol'shee znachenie
schetchika  - poleznoe svojstvo pri sozdanii ramok.   Otmetim,  chto
dazhe esli vyvoditsya mnogo  simvolov,  to poziciya kursora ne izme-
nyaetsya.   Kogda  stroka vyvodimyh simvolov zajmet  vse  svobodnoe
prostranstvo ekrana sprava-vniz  ot kursora, to vyvod budet pere-
nesen v pervye pozicii ekrana.

;---vyvod simvola v negative
   MOV  AH,9             ;funkciya zapisi s atributami
   MOV  AL,THE_CHARACTER    ;simvol v AL
   MOV  BL,112           ;atributy v BL
   MOV  BH,0             ;stranica 1
   MOV  CX,1             ;vyvesti odin raz
   INT  10H

Vmesto  togo, chtoby postoyanno vosstanavlivat' znachenie schetchika v
CX preryvanie  BIOS  predostavlyaet  takzhe  teletajpnuyu proceduru,
kotoraya  bol'she podhodit dlya vyvoda stroki simvolov.  Ona  vypol-
nyaetsya funkciej E.  Ona  gotovitsya tak zhe, kak i funkciya A, no ne
nado  zasylat'  znachenie v CX.  Stroka vyvoditsya prosto  za  schet
izmeneniya simvola v AL i  povtornogo  vyzova  preryvaniya. Pri is-
pol'zovanii v graficheskom rezhime v BL ustanavlivaetsya cvet palet-
ty, v protivnom sluchae sohranyaetsya staryj atribut.

;---vyvod stroki s pomoshch'yu teletajpnoj procedury
            MOV  AH,0EH     ;nomer funkcii
            MOV  BH,0       ;nomer stranicy
            LEA  BX,STRING  ;BX ukazyvaet na stroku
NEXT_CHAR:  MOV  AL,[BX]    ;berem simvol v AL
            CMP  AL,'$'     ;proverka na konec stroki
            JE   ALL_DONE   ;esli da, to vyhod
            INT  10H        ;vyvod stroki
            INC  BX         ;perehodim k sleduyushchemu simvolu
            JMP  SHORT NEXT_CHAR   ;povtoryaem proceduru
ALL_DONE:

   Preryvanie DOS 21H kak  pravilo  predostavlyaet  bolee poleznye
procedury,  poskol'ku oni peremeshchayut kursor i  privodyat k  sdvigu
ekrana pri dostizhenii nizhnej stroki, a takzhe interpretiruyut neko-
torye iz obychnyh upravlyayushchih kodov.  Funkcii DOS vyvodyat na stra-
nicu, kotoraya dolzhna byt'  ustanovlena  funkciej 5 preryvaniya 10H
[4.5.3].  Predostavlyayutsya dve funkcii dlya vyvoda simvola, s nome-
rami 2 i 6. Pervaya iz nih raspoznaet Ctrl-Break [3.2.8], a vtoraya
-  net.   (Kogda s klaviatury vvoditsya Ctrl-Break,  to  procedura
obrabotki Ctrl-Break ne  vypolnyaetsya  do teh por, poka ne ispol'-
zuetsya funkciya, kotoraya raspoznaet ego nalichie).
   Obe funkcii vyvodyat belye simvoly na chernom fone, do teh  por,
poka ne sdelana  special'naya  ustanovka  cveta s pomoshch'yu drajvera
ustrojstva ANSI.SYS [4.1.3].  V obshchem neobhodimo tol'ko pomestit'
simvol v DL, nomer funkcii v AH i  vyzvat' preryvanie 21H. Odnako


funkciya 6 osobennaya v tom smysle, chto ona imeet vtoroe naznachenie
v kachestve funkcii vvoda s klaviatury.  Ona vystupaet v etoj roli
tol'ko  esli v DL pomeshchen kod FF [3.1.5].  Vo vseh ostal'nyh slu-
chayah ona vyvodit na  ekran  soderzhimoe  DL.  V  sleduyushchem primere
funkciya  6 poocheredno prinimaet i pechataet simvol (v [3.1.4]  ob-
suzhdaetsya procedura, kotoraya kombiniruet oba etih svojstva).

       MOV  AH,6       ;nomer funkcii
NEXT:  MOV  DL,0FFH    ;pri etom znachenii prinimaem vvod
       INT  21H        ;vypolnyaem preryvanie
       JZ   NEXT       ;esli ne bylo vvoda, to obratno
       CMP  AL,13      ;eto byl vozvrat karetki?
       JE   END_INPUT  ;esli da, to na konec
       MOV  DL,AL      ;inache posylaem simvol v DL
       INT  21H        ;i vyvodim ego na ekran
       JMP  SHORT NEXT ;povtoryaem proceduru

   Nizkij uroven'.

   Na  nizhnem  urovne  ves' vyvod na ekran  osushchestvlyaetsya  cherez
otobrazhenie v pamyat'.  |tu  tehniku  ne rekomenduyut ispol'zovat',
chtoby ne stolknut'sya s problemoj sovmestimosti s budushchimi pokole-
niyami mashin, odnako do sih por IBM delalo videobufer svoih mikro-
komp'yuterov ustroennym odinakovo i raspolozhennym v odnih i teh zhe
adresah pamyati.  Poskol'ku bufer ustroen takim obrazom, chto bajty
atributov  peremezhayutsya s bajtami simvolov, to simvol'nye  dannye
ne mogut prosto peresylat'sya iz pamyati v bufer instrukciej MOVSB,
poskol'ku  ukazatel'  v bufere dolzhen uvelichivat'sya na dva  posle
kazhdogo perenosa bajta.  Odnako,  ispol'zovanie  etoj tehniki su-
shchestvenno  uskoryaet  vyvod na ekran.  Otmetim, chto otobrazhenie  v
pamyat' ne rabotaet pri vyvode  simvolov  v  graficheskom rezhime. V
etom  sluchae razmer videobufera 16K ili 32K i BIOS risuet  kazhdyj
simvol potochechno.  Otmetim takzhe, chto pri otobrazhenii v pamyat' ne
ispol'zuetsya  kursor dlya ukazaniya na simvol.  Pri  zhelanii  mozhno
peremeshchat' kursor po mere vvoda  [4.2.1] ili vyklyuchit' ego i soz-
dat' svoj psevdokursor [4.2.6].

;---v segmente dannyh
SAMPLE_STRING  DB   'PRINT THIS STRING$'

;---vyvod stroki
       MOV  AX,0B000H            ;monohromnyj displej
       MOV  ES,AX                ;ukazyvaem na videobufer
       LEA  BX,SAMPLE_STRING     ;BX ukazyvaet na stroku
       MOV  DI,CURSOR_START      ;nachal'naya poziciya v bufere
NEXT:  MOV  AL,[BX]              ;berem simvol
       CMP  AL,'$'               ;proverka na konec stroki
       JE   ALL_DONE             ;esli da, to vyhod
       MOV  ES:[DI],AL           ;inache pomeshchaem simvol v bufer
       INC  DI                   ;uvelichivaem ukazatel' na 2
       INC  DI                   ;
       INC  BX                   ;perehodim k obrabotke sledu-
       JMP  SHORT NEXT           ;shchego simvola
ALL_DONE:


   U  cvetnogo graficheskogo adaptora i PCjr (no ne u EGA) imeetsya
problema, svyazannaya s  otobrazheniem  v pamyat'. Kogda zapis' v bu-
fernuyu  pamyat' proishodit odnovremenno s chteniem ee dlya vyvoda na
ekran, to na ekrane voznikaet interferenciya. |ta problema reshaet-
sya  ozhidaniem  signala "vse chisto" (all clear)  pered  zapis'yu  v
videobufer. Nado nepreryvno chitat' znachenie iz porta 3DAH.  Kogda
bit 0 raven 1, to mozhno spokojno pisat'.  (3DAH - eto port, cherez
kotoryj PCjr posylaet dannye massivu vorot displeya; kogda iz nego
chitaem,  to on vozvrashchaet registr statusa, kak i u cvetnogo adap-
tora.)

;---ozhidaem poka vse chisto
        MOV  DX,3DAH          ;port registra statusa
CHECK_AGAIN:   IN   AL,DX     ;poluchaem znachenie
        TEST AL,1             ;proverka pervogo bita
        JNE  CHECK_AGAIN      ;esli on 0, to obratno
;---teper' vyvodim soobshchenie
        LEA  BX,MESSAGE       ;soobshchenie v segmente dannyh
        MOV  DI,2000          ;nachinaem vyvod s centra ekrana
        MOV  AH,01000001B     ;atribut sinij na krasnom
NEXT_CHAR:   MOV  AL,[BX]     ;berem simvol
        CMP  AL,'$'           ;proveryaem na konec stroki
        JE   ALL_DONE         ;esli konec, to na vyhod
        MOV  ES:[DI],AX       ;inache vyvodim simvol
        INC  BX               ;uvelichivaem ukazatel' stroki
        INC  DI               ;uvelichivaem ukazatel' bufera
        INC  DI               ;
        JMP  SHORT NEXT_CHAR  ;obrabatyvaem sleduyushchij simvol
ALL_DONE:

   Vy mozhete poeksperimentirovat'  skol'ko  simvolov za odin cikl
mozhet vyvodit' Vasha procedura bez poyavleniya interferencii. Imejte
vvidu, chto pri pervom vypolnenii cikla testiruemyj bit mozhet byt'
ravnym  edinice, no mozhet ne ostavat'sya vremeni, chtoby  zavershit'
operaciyu zapisi.
   PCjr  special'no  skonstruirovan   takim  obrazom, chto vyvod v
adresa, ispol'zuemye buferom cvetnogo graficheskogo displeya  pere-
napravlyaetsya v tu  oblast'  pamyati,  gde  na samom dele nahoditsya
bufer.   |to  svojstvo pozvolyaet delat' programmnoe  obespechenie,
podhodyashchee dlya oboih sistem.





   Procedury, kotorye vyvodyat celye  stroki simvolov ochen' polez-
ny, no oni mogut nakladyvat' ogranicheniya na soderzhimoe  vyvodimoj
stroki. Nado  obrashchat'  vnimanie  na  to,  kakie upravlyayushchie kody
(tabulyaciya,  probel  i t.p.) interpretiruyutsya, a kakie  net.   Do
poyavleniya AT BIOS ne  imel  funkcii  vyvoda  stroki,  hotya MS DOS
vsegda  imela takuyu fuknciyu.  Funkciya BIOS predostavlyaet  bol'shij
kontrol' nad atributami simvolov. Estestvenno, chto ee ispol'zova-
nie sozdaet problemu sovmestimosti s predydushchimi mashinami.  Napo-
minaem, chto EGA imeet PZU, rasshiryayushchee  ROM-BIOS i funkciya vyvoda
stroki simvolov yavlyaetsya odnim iz takih rasshirenij. V etom sluchae
lyuboj IBM PC i XT imeet vozmozhnost' ispol'zovat' etu proceduru.

   Vysokij uroven'.

   Bejsik vyvodit stroku tochno  tak  zhe, kak i otdel'nye simvoly.
Nado  prosto  napisat' PRINT S$, gde S$ mozhet byt' lyuboj  strokoj
dlinoj do 255 simvolov, kotoruyu  skonstruirovala  programma.  In-
terpretiruyutsya 10 upravlyayushchih kodov, a imenno:

   ASCII   7          zvonok
   ASCII   9          tabulyaciya
   ASCII  10          perevod stroki
   ASCII  11          kursor v pervuyu poziciyu ekrana (Home)
   ASCII  12          perevod formata (stiraet ekran + Home)
   ASCII  13          vozvrat karetki
   ASCII  28          kursor vpravo
   ASCII  29          kursor vlevo
   ASCII  30          kursor vverh
   ASCII  31          kursor vniz

Vse ostal'nye kody vyvodyatsya na ekran kak simvoly.

   Srednij uroven'.

   Funkciya  9 preryvaniya 21H vyvodit stroku.  DS:DX dolzhny ukazy-
vat' na pervyj simvol stroki.  Stroka dolzhna zavershat'sya simvolom
$,  chto  oznachaet,  chto sam simvol $ ne mozhet  vhodit' v  stroku.
Stroka mozhet byt' lyuboj dliny. Funkciya ne perevodit avtomaticheski
kursor na nachalo sleduyushchej stroki posle zaversheniya vyvoda;  chtoby
eto vypolnyalos' nado dobavit' v konec stroki simvoly 0AH (perevod
stroki) i 0DH (vozvrat karetki).

;---v segmente dannyh
FIRST_STRING    DB   'This is the first string',0AH,0DH,'$'
SECOND_STRING   DB   'And this is the second string$'

;---vyvod stroki
   MOV  AH,9             ;nomer funkcii vyvoda stroki
   LEA  DX,FIRST_STRING  ;zagruzhaem adres pervoj stroki
   INT  21H              ;pechataem stroku s pozicii kursora
   LEA  DX,SECOND_STRING ;zagruzhaem adres vtoroj stroki
   INT  21H              ;pechataem stroku s nachala novoj stroki


Intrepretiruyutsya sleduyushchie upravlyayushchie kody:

   ASCII   7           zvonok
   ASCII   8           vozvrat na shag (BackSpace)
   ASCII   9           tabulyaciya
   ASCII  10           perevod stroki
   ASCII  13           vozvrat karetki

   Funkciya  DOS 40H preryvaniya 21H takzhe polezna pri vyvode strok
na ekran.  Ona trebuet, chtoby Vy znali dlinu stroki, poskol'ku ej
ne  trebuetsya  simvola-ogranichitelya; eta funkciya osobenno  udobna
dlya dampa tekstovyh fajlov  na  ekran.  Ishodno  eta funkciya byla
prednaznachena dlya vyvoda v fajl. Ona trebuet deskriptora, kotoryj
yavlyaetsya  identifikacionnym  nomerom  dlya  dannogo fajla ili ust-
rojstva.   Displej  imeet zaranee prednaznachennyj deskriptor  #1.
Nado pomestit' deskriptor v BX, a chislo bajtov stroki v CX. DS:DX
dolzhny  ukazyvat' na stroku.  Funkciya vyvodit tekst s normal'nymi
(belyj na chernom) atributami. Otmetim, chto ne nado predvaritel'no
"otkryvat'"  displej,  kak eto Vy delaet s  drugimi  fajlami  pri
ispol'zovanii etoj funkcii. Vot primer:

;---vyvod 1000 bajtov teksta
   MOV  AH,40H          ;nomer funkcii
   MOV  BX,1            ;deskriptor displeya
   LEA  DX,STRING       ;zagrzhaem adres stroki
   MOV  CX,1000         ;chislo vyvodimyh bajtov
   INT  21H             ;

   MS DOS predostavlyaet  nabor  Esc-posledovatel'nostej,  kotorye
yavlyayutsya special'nymi upravlyayushchimi strokami dlya apparatury. Kogda
oni vyvodyatsya s pomoshch'yu  funkcii  9  preryvaniya 21H, to oni mogut
upravlyat' kursorom, rezhimom displeya, cvetom simvolov i nekotorymi
aspektami klaviatury. V prilozhenii D obsuzhdaetsya kak ih ispol'zo-
vat'. Kogda programma vyvodit na ekran mnogo strok, to Esc-posle-
dovatel'nosti chasto yavlyayutsya  samym udobnym sposobom pozicioniro-
vaniya  kursora i ustanovki cveta stroki.  |to proishodit  potomu,
chto oni sami rassmatrivayutsya prosto  kak ocherednye stroki v serii
vyvodimyh strok.
   U AT i mashin, snabzhennyh EGA, funkciya 13H preryvaniya 10H vyvo-
dit stroku.  ES:BP  dolzhny  ukazyvat'  na  stroku, a dlina stroki
dolzhna byt' v CX.  DX ukazyvaet poziciyu kursora, s kotoroj dolzhna
nachinat'sya stroka (vychislyaemuyu  kak  smeshchenie ot nachala stranicy,
na  kotoruyu idet vyvod bez ucheta bajtov atributov).  V BX  dolzhen
byt' ukazan nomer stranicy.  Nakonec nomer koda ot 0 do 3, soder-
zhashchijsya v AL ukazyvaet kak dolzhna vyvodit'sya stroka.

   AL = 0    stroka sostoit tol'ko iz simvolov, kursor nepodvizhen
   AL = 1    stroka sostoit tol'ko iz simvolov, kursor dvizhetsya
   AL = 2    v stroke chereduyutsya simvoly i atributy,
             kursor nepodvizhen
   AL = 3    v stroke chereduyutsya simvoly i atributy
             kursor dvizhetsya


Kogda AL ravno 0 ili 1, to atributy dolzhny nahodit'sya v BL.   Vse
simvoly budut vyvodit'sya s etimi atributami.  |ta funkciya interp-
retiruet vozvrat na shag, perevod stroki, vozvrat karetki i zvonok
kak upravlyayushchie komandy, a ne kak pechataemye simvoly.

   Nizkij uroven'.

   Ogranichenie na ispol'zovanie simvola $ delaet funkciyu 9 bespo-
leznoj  dlya  mnogih prilozhenij.  Odnako na mnogih mashinah eto  e-
dinstvennoe preryvanie,  dostupnoe  dlya vyvoda stroki neizvestnoj
dliny. Poprobujte napisat' svoe sobstvennoe preryvanie (v [1.2.3]
pokazano kak), ispol'zuyushchee tehniku otobrazheniya v pamyat' [4.3.1].
Ispol'zujte  v  kachestve  ogranichitelya  kakoj-nibud'  special'nyj
simvol, naprimer, ASCII 0, vmesto $. Sdelajte chtoby eta procedura
obrabatyvala tol'ko te upravlyayushchie kody, kotorye nuzhny Vam. Takoj
metod budet rabotat' namnogo bystree, chem pri ispol'zovanii funk-
cii MS DOS.





   Obychno  programma poluchaet dannye iz svoih peremennyh i  pome-
shchaet ih v videobufer  dlya  vyvoda  na  ekran.  V nekotorom smysle
programma "znaet" chto na ekrane. No vstrechayutsya situacii, v koto-
ryh sam videobufer ispol'zuetsya  kak rabochaya oblast' (naprimer, v
grafichenskih  programmah vyrezki i vstavki) i tekushchee  soderzhimoe
ekrana ne zapisano v  pamyati  programmy.   V  etih sluchayah byvaet
neobhodimo prochitat' s ekrana, viesto togo chtoby vyvesti na nego.
Funkciya BIOS pozvolyaet prochitat'  simvol i ego atributy v oprede-
lennoj  pozicii  ekrana; drugoj metod sostoit v obrashchenii  metoda
pryamogo otobrazheniya v  pamyat'  displeya  [4.3.1].  CHtoby prochitat'
simvol  i  atributy  v stroke 0 i stolbce 39 (1,40 v  Bejsike)  v
rezhime 80 simvolov v stroke  nado  slozhit'  (0*160) plyus (39*2) i
vzyat' rezul'tat v kachestve smesheniya v videobufere. V sluchae kogda
nuzhny smeshcheniya dlya razlichnyh  stranic  sm. [4.5.3]. Imejte vvidu,
chto  obrashchenie metoda pryamogo otobrazheniya v pamyat' ne budet rabo-
tat' v sluchae vyvoda simvolov v graficheskom rezhime.

   Vysokij uroven'.

   Bejsik ispol'zuet  funkciyu  SCREEN  dlya  polucheniya simvola ili
atributov (eta funkciya ne imeet nichego obshchego s operatorom SCREEN
ustanavlivayushchim rezhim  displeya).  SCREEN  5,10 poluchaet kod ASCII
simvola,  raspolozhennogo v stroke 5, stolbce 10 (stroki i stolbcy
numeruyutsya ot 1).  CHtoby  poluchit' atributy simvola nado dobavit'
tretij parametr 1, naprimer, SCREEN 5,10,1.  Pri ispol'zovanii  v
graficheskom rezhime  dannaya  funkciya  vozvrashchaet 0, esli trebuemaya
poziciya ekrana ne soderzhit (nemodificirovannogo) simvola.
   Atributy takzhe vozvrashchayutsya v vide koda ot 0 do 255. Poskol'ku
Bejsik  ne  pozvolyaet ispol'zovaniya dvoichnyh chisel, to  trebuyutsya
nekotorye manipulyacii, chtoby  opredelit'  atributy. Osnovnoj cvet
raven ATTRIBUTE MOD 16. Posle togo kak Vy vydelili osnovnoj cvet,
cvet fona opredelyaetsya po  formule  (((ATTIBUTE - FOREGROUND)/16)
MOD  128).   Esli bajt atributov bol'she 127, to vklyucheno  miganie
(ili, pri sootvetstvuyushchej  ustanovke,  vklyucheny intensivnye cveta
fona  [4.1.3]).   V prilozhenii B obsuzhdayutsya bitovye  operacii  v
Bejsike.

   Srednij uroven'.

   Funkciya 8 preryvaniya 10H vozvrashchaet  simvol i ego atributy dlya
tekushchej  pozicii kursora.  V BH dolzhen soderzhat'sya nomer  tekushchej
stranicy displeya (otschityvaemyj ot 0 i vsegda ravnyj 0 dlya monoh-
romnogo displeya). Kod simvola vozvrashchaetsya v AL, a bajt atributov
v  AH.   |ta funkciya nastol'ko moshchnaya, chto sposobna  dazhe  chitat'
simvoly v graficheskom  rezhime,  soobshchaya  cvet  paletty  v AH. Ona
rabotaet dazhe dlya simvolov opredelyaemyh pol'zovatelem [4.3.4].  V
primere opredelyaetsya simvol i atributy v pozicii 0,39 dlya strani-
cy 2 graficheskogo adaptora:


;---ustanovka pozicii kursora
   MOV  AH,2        ;funkciya ustanovki kursora
   MOV  DH,0        ;nomer stroki
   MOV  DL,39       ;nomer stolbca
   MOV  BH,0        ;nomer stranicy
   INT  10H         ;pozicioniruem kursor
;---chtenie simvola i atributov
   MOV  AH,8        ;funkciya chteniya simvola/atributov
   MOV  BH,2        ;nomer stranicy
   INT  10H         ;v AH:AL teper' atributy i simvol

   Nizkij uroven'.

   Nado  vychislit' smeshchenie i prodelat' operaciyu obratnuyu  pryamoj
zapisi v pamyat'.  Pri  neobhodimosti  nado  dobavit' smeshchenie dlya
dannoj  stranicy.  V primere poluchaem simvol i atributy v pozicii
7,39 stranicy 2 graficheskogo adaptora:

;---chtenie simvola i atributov pozicii 7,39 stranicy 2
   MOV  AX,0B800H       ;adres videobufera
   MOV  ES,AX           ;ES ukazyvaet na pervyj bajt bufera
   MOV  DI,1000H        ;smeshchenie do nachala stranicy
   MOV  AL,80           ;umnozhaem nomer stroki na 160
   MOV  BL,7            ;nomer stroki
   MUL  BL              ;teper' v AX (stroka-1)*160
   MOV  AX,39           ;nomer stolbca
   ADD  BX,AX           ;nomer pozicii v videobufere
   SHL  BX,1            ;umnozhaem ego na dva
   MOV  AX,ES:[BX][DI]  ;teper' AH:AL soderzhat atributy/simvol





   Tol'ko  monohromnyj  adaptor ne mozhet vyvodit'  simvoly  vida,
zadannogo  samim  programmistom.  Cvetnoj  adaptor  pozvolyaet 128
simvolov, opredelyaemyh pol'zovatelem, PCjr - 256, a EGA - 1024 iz
kotoryh odnovremenno dostupno 512. Dlya cvetnogo adaptora ROM-BIOS
soderzhit  dannye dlya razrisovki tol'ko pervyh 128 simvolov nabora
ASCII (s nomerami ot 0 do 127). Sleduyushchie 128 simvolov nedostupny
dlya Vas, poka Vy ne sozdatite ih, ispol'zuya opisannuyu zdes'  teh-
niku. Otmetim, chto MS DOS  3.00  predostavlyaet  komandu GRAFTABL,
kotoraya  predostavlyaet trebuemye dannye dlya vtoroj porcii iz  128
simvolov. PCjr imeet dannye dlya vtoroj porcii iz 128 simvolov uzhe
gotovye. EGA imeet polnye nabory simvolov dlya rezhimov s 200 stro-
kami i s 350 strokami.
   Simvoly dlya graficheskogo adaptora i PCjr opisyvayutsya s pomoshch'yu
matricy 8*8 tochek. Dannye dlya kazhdogo simvola soderzhatsya v vos'mi
bajtah. Kazhdyj bajt  soderzhit  ustanovku  dlya  tochek odnogo ryada,
nachinaya s verhnego ryada, prichem starshij bit (nomer 7)  sootvetst-
vuet samoj levoj tochke v ryadu. Kogda sootvetstvuyushchij bit raven 1,
to tochka vysvechivaetsya. Dlya opisaniya simvola Vy dolzhny opredelit'
pravil'nye posledovatel'nosti bitov dlya vos'mi bajtov i pomestit'
ih v posledovatel'nye yachejki pamyati.  Na ris.  4-3 pokazano kak 8
bajtov opisyvayut bubnovuyu mast'.
   Vse 128  simvolov  vmeste  trebuyut  1024  bajta, hotya vovse ne
trebuetsya,  chtoby byli opisany vse simvoly.   Special'nyj  vektor
preryvaniya   (postoyannyj   ukazatel'   v   mladshih adresah pamyati
[1.2.0])  ukazyvaet na adres pervogo bajta pervogo simvola rasshi-
rennogo nabora, t.e. na simvol nomer 128. Kogda v poziciyu simvola
v videobufere posylaetsya kod 128, to prosmatrivayutsya i  vyvodyatsya
pervye vosem' bajt. Esli nomer  simvola 129, to vyvodyatsya bajty s
devyatogo po shestnadcatyj, i t.d.
   Nomer  etogo vektora preryvaniya 1FH i on raspolozhen po  adresu
0000:007C. Pomestite znachenie  smeshcheniya  v mladshee slovo (snachala
mladshij bajt), a adres segmenta - v starshee slovo (snova, snachala
mladshij bajt).  Otmetim,  chto  mozhno  simvoly s bol'shimi nomerami
kodov,  ne  otvodya pamyati dlya simvolov s men'shimi nomerami;  nado
prosto chtoby vektor ukazyval na nekotoryj  adres, kotoryj men'she,
chem adres nachala bloka, soderzhashchego dannye dlya opisaniya simvolov.
Vos'mibajtnye  posledovatel'nosti,   opisyvayushchie  simvoly ASCII s
kodami  128-255 privedeny v [4.3.5].  U PCjr vektor 1FH ukazyvaet
na vtorye 128 simvolov ASCII, a vektor  44H - na pervye. Oba etih
vektora mogut byt' izmeneny, dopuskaya polnyj nabor 256  simvolov,
opredelyaemyh pol'zovatelem.
   Dlya EGA kartina namnogo slozhnee, no i namnogo gibche.  Pri ini-
cializacii  tekstovogo rezhima odin iz dvuh naborov simvolov  (8*8
ili 8*14) kopiruetsya iz PZU EGA v  kartu bitov 2 videobufera. |ta
chast' bufera rassmatrivaetsya kak razbitaya na bloki, prichem  stan-
dartnyj nabor simvolov pomeshchaetsya v blok 0.  Pri uslovii, chto EGA
osnashchen  dostatochnoj pamyat'yu mogut byt' opredeleny eshche tri  bloka
dlya opisaniya simvolov.   Razmer  bloka  opredelyaetsya chislom strok
matricy, ispol'zuemoj dlya opisaniya simvola.  Simvoly, opisyvaemye
matricej 8*8 trebuyut 8*256 ili  2048  bajt. Kogda razresheny bolee
odnogo  bloka  simvolov, to bit 3 bajta atributov  opredelyaet  iz
kakogo bloka budut brat'sya dannye dlya opisaniya simvola.


   Kakoj iz  blokov  budet  ispol'zovat'sya  zavisit  ot ustanovki
bitov  0-3  registra vybora karty simvolov, adres porta  kotorogo
3C5H.  Predvaritel'no nado  poslat'  3 v port 3C4H, chtoby ukazat'
trebuemyj  registr.  Bity 1-0 dayut nomer bloka simvolov,  kotoryj
beretsya kogda bit 3 bajta  atributov raven 0, a bity 3-2 - delayut
to zhe samoe, kogda bit 3 raven 1. Kogda ustanovka oboih par bitov
sovpadaet, to  vozmozhnost'  ispol'zovaniya  dvuh  naborov simvolov
otsutstvuet  i bit 3 bajta atributov pereklyuchaetsya  na  ustanovku
intensivnosti simvola. V etom  sluchae ispol'zuetsya tol'ko blok 0.
Odnako nikto ne mozhet pomeshat' Vam pomestit' svoi simvoly v lyubuyu
nuzhnuyu Vam poziciyu v etom  bloke.   Esli  Vy izmenili standartnyj
nabor  simvolov, to Vy mozhete v lyuboj moment vosstanovit' ego  iz
PZU.

   Vysokij uroven'.

   V Bejsike Vy dolzhny pozabotit'sya o tom, chtoby dannye opisyvayu-
shchie simvoly nahodilis' za predelami pamyati, ispol'zuemoj program-
moj. Esli imeetsya mnogo pamyati, to mozhno pomestit' dannye v star-
shie adresa; esli imeetsya opasnost' konflikta, to sleduet  ispol'-
zovat' komandu CLEAR dlya  ogranicheniya  kolichestva pamyati, kotoruyu
mozhet ispol'zovat' Bejsik.  Zatem sleduet pomestit' adres pervogo
bajta dannyh v vektor preryvaniya. V sleduyushchem primere opisyvaetsya
simvol 128 kak kvadratnaya ramka.  Operatory DATA soderzhat  znache-
niya, opisyvayushchie simvol. Oni  ravny  libo 255, libo 129; v pervom
sluchae vse bity ravny 1, a vo vtorom ravny 1 tol'ko krajnie bity.
O vychislenii desyatichnyh znachenij, sootvetstvuyushchih dannym cepochkam
bitov sm. prilozhenie B.

100 '''pomeshchaem dannye, nachinaya s adresa &H3000
110 DATA 255, 129, 129, 129, 129, 129, 129, 255
120 DEF SEG = &H3000    'ukazyvaem nachalo segmenta
130 FOR N = 0 TO 7      'opredelyaem 8 bajt
140 READ Q              'chitaem 1 bajt
150 POKE N,Q            'pomeshchaem ego v pamyat'
160 NEXT                'i t.d.
170 '''ustanovka vektora preryvaniya
180 DEF SEG = 0         'ukazyvaem na nachalo pamyati
190 POKE 124,0          'ukazyvaem smeshchenie
200 POKE 125,0          '
210 POKE 126,0          'ukazyvaem segment
220 POKE 127,&H30       '
230 '''pechataem simvol
240 LOCATE 12,12: PRINT CHR$(128)  'teper' est' simvol 128

   Srednij uroven'.

   Dlya cvetnogo adaptora i PCjr ispol'zujte funkciyu 25H  preryva-
niya 21H dlya izmeneniya vektora  preryvaniya  1FH.   Pri vhode DS:DX
dolzhny  ukazyvat'  na pervyj bajt bloka dannyh.  Bolee  podrobnoe
opisanie sm. v [1.2.3]. V primere sozdayutsya dva simvola s nomera-
mi 128 i 129.  Oni yavlyayutsya zerkal'nymi otobrazheniyami drug druga,
a vyvedennye podryad obrazuyut nebol'shoj pryamougol'nik.


;---v segmente dannyh
CHARACTER_DATA   DB  11111111B, 10000000B, 10000000B, 10000000B
                 DB  10000000B, 10000000B, 10000000B, 11111111B
                 DB  11111111B, 00000001B, 00000001B, 00000001B
                 DB  00000001B, 00000001B, 00000001B, 11111111B

;---ustanovka vektora preryvaniya
   PUSH DS                ;sohranyaem DS
   LEA  DX,CHAR_DATA      ;smeshchenie dlya dannyh v DX
   MOV  AX,SEG CHAR_DATA  ;segment dlya dannyh v DS
   MOV  DS,AX             ;
   MOV  AH,25H            ;funkciya ustanovki vektora
   MOV  AL,1FH            ;nomer izmenyaemogo vektora
   INT  21H               ;ustanovka vektora
   POP  DS                ;vosstanavlivaem DS

;---pechat' simvolov
   MOV  AH,2              ;nomer funkcii
   MOV  DL,128            ;pervyj simvol
   INT  21H               ;vyvod ego
   MOV  DL,129            ;vtoroj simvol
   INT  21H               ;vyvod ego

   Dlya EGA funkciya 11H preryvaniya 10H manipuliruet naborom simvo-
lov. |ta funkciya mozhet byt' ochen' slozhnoj, kogda ona ispol'zuetsya
dlya sozdaniya special'nyh rezhimov  ekrana, no ee osnovnoe primene-
nie dostatochno prostoe. Imeetsya chetyre podfunkcii. Kogda AL raven
0, to dannye, opredelyaemye  pol'zovatelem perenosyatsya iz pamyati v
special'nyj  blok  simvolov.  Kogda AL raven 1 ili 2,  to  nabory
dannyh dlya simvolov 8*14 i 8*8 sootvetstvenno kopiruyutsya iz PZU v
blok simvolov.  Kogda AL raven 3, to funkciya ustanavlivaet nazna-
chenie bloka v registre vybora karty simvolov, kak opisano vyshe. V
poslednem sluchae nado prosto pomestit' sootvestvuyushchie dannye v BL
i vyzvat' funkciyu.  Dlya  zagruzki  dannyh  iz PZU pomestite nomer
bloka  v BL i vypolnite funkciyu.  Dlya zagruzki svoih dannyh  nado
chtoby ES:BP ukazyvali na nih,  chislo peredavaemyh simvolov dolzhno
byt'  v  CX, smeshchenie (nomer simvola) v bloke dolzhno  byt' v  DX,
chislo bajtov na simvol - v BH, a nomer bloka - v BL.  Posle etogo
vyzyvajte preryvanie 10H. Vot primer:

;---ustanavlivaem 128 pol'zovatel'skih simvolov v bloke 0
   MOV  AX,SEG CHARACTER_DATA   ;ES:BP dolzhny ukazyvat' na dannye
   MOV  ES,AX                   ;
   MOV  BP,OFFSET CHARACTER_DATA   ;
   MOV  CX,128                  ;chislo simvolov
   MOV  DX,128                  ;nachal'noe smeshchenie
   MOV  BL,0                    ;nomer bloka
   MOV  BH,8                    ;matrica 8*8
   MOV  AL,1                    ;nomer podfunkcii
   MOV  AH,11H                  ;nomer funkcii
   INT  10H                     ;perenosim dannye





   Nizhe  privedeny 8-bajtnye posledovatel'nosti, neobhodimye  dlya
opisaniya simvolov dlya cvetnogo graficheskogo  adaptora. Ih ispol'-
zovanie ob®yasneno v [4.3.4].

   Kod ASCII      Simvol        Posledovatel'nost' (16-naya)

      128           A           78 CC C0 CC 78 18 0C 78
      129           B           00 CC 00 CC CC CC 7E 00
      130           V           1C 00 78 CC FC C0 78 00
      131           G           7E C3 3C 06 3E 66 3F 00
      132           D           CC 00 78 0C 7C CC 7E 00
      133           E           E0 00 78 0C 7C CC 7E 00
      134           ZH           30 30 78 0C 7C CC 7E 00
      135           Z           00 00 78 0C 7C CC 7E 00

      136           I           7E C3 3C 66 7E 60 3C 00
      137           J           CC 00 78 CC FC C0 78 00
      138           K           E0 00 78 CC FC C0 78 00
      139           L           CC 00 70 30 30 30 78 00
      140           M           7C C6 38 18 18 18 3C 00
      141           N           E0 00 70 30 30 30 78 00
      142           O           C6 38 6C C6 FE C6 C6 00
      143           P           30 30 00 78 CC FC CC 00

      144           R           1C 00 FC 60 78 60 FC 00
      145           S           00 00 7F 0C 7F CC 7F 00
      146           T           3E 6C CC FE CC CC CE 00
      147           U           78 CC 00 78 CC CC 78 00
      148           F           00 CC 00 78 CC CC 78 00
      149           H           00 E0 00 78 CC CC 78 00
      150           C           78 CC 00 CC CC CC 7E 00
      151           CH           00 E0 00 CC CC CC 7E 00

      152           SH           00 CC 00 CC CC 7C 0C F8
      153           SHCH           C3 18 3C 66 66 3C 18 00
      154           ¬           CC 00 CC CC CC CC 78 00
      155           Y           18 18 7E C0 C0 7E 18 18
      156           X           38 6C 64 F0 60 E6 FC 00
      157           |           CC CC 78 FC 30 FC 30 30
      158           YU           F8 CC CC FA C6 CF C6 C7
      159           YA           0E 1B 18 3C 18 18 D8 70

      160           a           1C 00 78 00 7C CC 7E 00
      161           b           38 00 70 30 30 30 78 00
      162           v           00 1C 00 78 CC CC 78 00
      163           g           00 1C 00 CC CC CC 7E 00
      164           d           00 F8 00 F8 CC CC CC 00
      165           e           FC 00 CC EC FC DC CC 00
      166           zh           3C 6C 6C 3E 00 7E 00 00
      167           z           38 6C 6C 38 00 7C 00 00


      168           i           30 00 30 60 C0 CC 78 00
      169           j           00 00 00 FC C0 C0 00 00
      170           k           00 00 00 FC 0C 0C 00 00
      171           l           C3 C6 CC DE 33 66 CC 0F
      172           m           C3 C6 CC DB 37 6F CF 03
      173           n           18 18 00 18 18 18 18 00
      174           o           00 33 66 CC 66 33 00 00
      175           p           00 CC 66 33 66 CC 00 00

      176           °           22 88 22 88 22 88 22 88
      177           ±           55 AA 55 AA 55 AA 55 AA
      178           ˛           DB 77 DB EE DB 77 DB EE
      179           ł           18 18 18 18 18 18 18 18
      180           ´           18 18 18 18 F8 18 18 18
      181           µ           18 18 F8 18 F8 18 18 18
      182           ¶           36 36 36 36 F6 36 36 36
      183           ·           00 00 00 00 FE 36 36 36

      184           ¸           00 00 F8 18 F8 18 18 18
      185           ą           36 36 F6 06 F6 36 36 36
      186           ş           36 36 36 36 36 36 36 36
      187           »           00 00 FE 06 F6 36 36 36
      188           Ľ           36 36 F6 06 FE 00 00 00
      189           ˝           36 36 36 36 FE 00 00 00
      190           ľ           18 18 F8 18 F8 00 00 00
      191           ż           00 00 00 00 F7 18 18 18

      192           A           18 18 18 18 1F 00 00 00
      193           B           18 18 18 18 FF 00 00 00
      194           V           00 00 00 00 FF 18 18 18
      195           G           18 18 18 18 1F 18 18 18
      196           D           00 00 00 00 FF 00 00 00
      197           E           18 18 18 18 FF 18 18 18
      198           ZH           18 18 1F 18 1F 18 18 18
      199           Z           36 36 36 36 37 36 36 36

      200           I           36 36 37 30 3F 00 00 00
      201           J           00 00 3F 30 37 36 36 36
      202           K           36 36 F7 00 FF 00 00 00
      203           L           00 00 FF 00 F7 36 36 36
      204           M           36 36 37 30 37 36 36 36
      205           N           00 00 FF 00 FF 00 00 00
      206           O           36 36 F7 00 F7 36 36 36
      207           P           18 18 FF 00 FF 00 00 00

      208           R           36 36 36 36 FF 00 00 00
      209           S           00 00 FF 00 FF 18 18 18
      210           T           00 00 00 00 FF 36 36 36
      211           U           36 36 36 36 3F 00 00 00
      212           F           18 18 1F 18 1F 00 00 00
      213           H           00 00 1F 18 1F 18 18 18
      214           C           00 00 00 00 3F 36 36 36
      215           CH           36 36 36 36 FF 36 36 36


      216           SH           18 18 FF 18 FF 18 18 18
      217           SHCH           18 18 18 18 F8 00 00 00
      218           ¬           00 00 00 00 1F 18 18 18
      219           Y           FF FF FF FF FF FF FF FF
      220           X           00 00 00 00 FF FF FF FF
      221           |           F0 F0 F0 F0 F0 F0 F0 F0
      222           YU           0F 0F 0F 0F 0F 0F 0F 0F
      223           YA           FF FF FF FF 00 00 00 00

      224           r           00 00 76 DC CB DC 76 00
      225           s           00 78 CC F8 CC F8 C0 C0
      226           t           00 CC C0 C0 C0 C0 00 00
      227           u           00 FE 6C 6C 6C 6C 6C 00
      228           f           FC CC 60 30 60 CC FC 00
      229           h           00 00 7E D8 D8 D8 70 00
      230           c           00 66 66 66 66 7C 60 C0
      231           ch           00 76 DC 18 18 18 18 00

      232           sh           FC 30 78 CC CC 78 30 FC
      233           shch           38 6C C6 FE C6 6C 38 00
      234           ®           38 6C C6 C6 6C 6C EE 00
      235           y           1C 30 18 7C CC CC 78 00
      236           '           00 00 7E DB DB 7E 00 00
      237           e           06 0C 7E DB DB 7E 60 C0
      238           yu           38 60 C0 F8 C0 60 38 00
      239           ya           78 CC CC CC CC CC CC 00

      240           ¨           00 FC 00 FC 00 FC 00 00
      241           ¸           30 30 FC 30 30 00 FC 00
      242           t           60 30 18 30 60 00 FC 00
      243           u           18 30 60 30 18 00 FC 00
      244           f           0E 1B 1B 18 18 18 18 18
      245           h           18 18 18 18 18 D8 D8 70
      246           c           30 30 00 FC 00 30 30 00
      247           ch           00 76 DC 00 76 DC 00 00

      248           sh           38 6C 6C 38 00 00 00 00
      249           shch           00 00 00 18 18 00 00 00
      250           ®           00 00 00 00 18 00 00 00
      251           y           0F 0C 0C 0C EC 6C 3C 1C
      252           '           78 6C 6C 6C 6C 00 00 00
      253           e           70 18 30 60 78 00 00 00
      254           yu           00 00 3C 3C 3C 3C 00 00
      255                       00 00 00 00 00 00 00 00




   Cvetnoj graficheskij adaptor imeet tri graficheskih rezhima, PCjr
- shest', a EGA - sem'.  Kak  ustanavlivat'  eti rezhimy pokazano v
[4.1.2].   Trebovaniya k razmeru pamyati sushchestvenno otlichayutsya dlya
razlichnyh rezhimov,  v  zavisimosti  ot  razresheniya ekrana i chisla
ispol'zuemyh cvetov.  V svoih uluchshennyh graficheskih rezhimah  EGA
ispol'zuet pamyat' displeya sovsem po-drugomu, chem ostal'nye video-
sistemy, no on tochno emuliruet ih ispol'zovanie pamyati pri rabote
v treh obshchih rezhimah.
   Snachala rassmotrim cvetnoj adaptor  i sistemu PCjr.  Dva cveta
(chernyj i belyj) trebuyut tol'ko odin bit pamyati dlya kazhdoj  tochki
na ekrane. CHetyre cveta zanimayut 2 bita, a 16 cvetov - 4 (8-cvet-
nye  rezhimy ne ispol'zuyutsya, poskol'ku tri bita, trebuyushchiesya  dlya
ih predstavleniya nel'zya  udobno  razmestit'  v  8 bit bajta). Dlya
vseh  rezhimov po vertikali imeetsya 200 tochek.  Nizkoe  razreshenie
(ispol'zuemoe tol'ko na PCjr) ispol'zuet  160 tochek po gorizonta-
li, srednee razreshenie - vdvoe bol'she (320 tochek) i vysokoe  raz-
reshenie - eshche vdvoe bol'she (640  tochek).   CHislo kilobajt pamyati,
trebuemoe dlya kazhdogo rezhtima privedeno v [4.5.3].
   V dvuh- i chetyrehcvetnom rezhimah PCjr imeet vybor lyubogo iz 16
dostupnyh cvetov. Cvetnoj adaptor bolee ogranichen.  V dvuhcvetnom
rezhime  on  vsegda ogranichen belym i chernym,  a v  chetyrehcvetnom
rezhime tol'ko cvet fona mozhet vybirat'sya iz 16 cvetov, v to vremya
kak osnovnoj cvet dolzhen brat'sya tol'ko iz dvuh  predopredelennyh
palett. Paletta 0 soderzhit korichnevyj, zelenyj i krasnyj cveta, a
paletta 1 - cian, magenta i belyj.
   V  otlichie ot tekstovyh dannyh v rezhimah 4-6 i 8-A graficheskie
dannye razbity na videostranice  na  chasti. V bol'shinstve rezhimov
dannye  razbivayutsya na dve chasti, pri etom pervaya polovina bufera
soderzhit dannye dlya  chetnyh  strok  ekrana,  a  vtoraya polovina -
dannye  dlya  nechetnyh strok (stroki numeruyutsya,  nachinaya s  verha
ekrana vniz). Odnako v 16-cvetnyh rezhimah PCjr bufer razmerom 32K
delitsya na chetyre chasti, kazhdaya  iz  kotoryh  soderzhit dannye dlya
kazhdoj chetvertoj stroki.
   V  4-cvetnyh rezhimah pervyj bajt bufera soderzhit informaciyu  o
samyh levyh tochkah stroki 0, prichem starshij bit otnositsya k samoj
levoj tochke.  Sleduyushchij bajt soderzhit informaciyu o sleduyushchem seg-
mente stroki i t.d. Dlya vsej stroki trebuetsya 80 bajt.  81-j bajt
soderzhit informaciyu o levom konce stroki 2.  V 16-cvetnyh rezhimah
kartina priblizitel'no takaya  zhe,  no dlya kazhdoj stroki trebuetsya
160  bajt i kazhdaya chast' bufera soderzhit dannye tol'ko dlya  vdvoe
men'shego chisla strok. Dlya  cvetnogo  graficheskogo adaptora chetnye
stroki zanimayut pamyat' so smeshcheniyami ot 0000 do 1F3FH, a nechetnye
- ot 2000H do 3F3FH. Promezhutok mezhdu 1F3FH i 2000H ignoriruetsya.
Dlya PCjr sootvetstvuyushchie yachejki mogut sushchestvenno razlichat'sya,  v
zavisimosti ot rezhima i chisla  ispol'zuemyh  stranic.   PCjr spe-
cial'no  ustroen takim obrazom, chto vyvod v 16K,  nachinayushchihsya  s
segmenta B800H perenapravlyaetsya  v tu oblast' pamyati, gde real'no
raspolozhen videobufer.  |to svojstvo pozvolyaet pisat'  programmy,
kotorye budut odinakovo rabotat' na cvetnom displee i PCjr.
   Dlya rezhimov ekrana EGA ot DH do 10H pamyat' organizovana sovsem
po-drugomu. Ona razdelyaetsya na odnu, dve ili chetyre bitovye plos-
kosti, kazhdaya iz kotoryh organizovana tak zhe, kak dlya cherno-belo-
go rezhima vysokogo razresheniya, opisannogo vyshe: kogda bajt dannyh
posylaetsya v opredelennyj adres  videobufera, to kazhdyj bit soot-


vetstvuet  tochke  na ekrane, prichem oni opisyvayut  gorizontal'nyj
segment stroki i bit 7  sootvetstvuet  samoj levoj tochke. Zapisy-
vayutsya  chetyre  takih bitovyh ploskosti, sootvetstvuyushchih odnim  i
tem zhe adresam v videobufere.   |to  otvodit kazhdoj tochke 4 bita,
chto pozvolyaet opisyvat' 16 cvetov. Na ris. 4-4 pokazany razlichnye
shemy raspredeleniya pamyati.
   V graficheskom rezhime mogut  vyvodit'sya  i  simvoly. Odnako oni
sozdayutsya ne obchynym sposobom, vmesto etogo BIOS vyrisovyvaet  ih
potochechno, ne izmenyaya fonovogo cveta.  Po etoj prichine takie veshchi
kak negativnoe izobrazhenie i miganie simvolov nedostupny v grafi-
cheskom rezhime. Ne vyvoditsya i kursor. BIOS mozhet chitat' i oprede-
lyat' ustanovku tochek v pozicii kursora, chtoby uznat' kakoj simvol
tam soderzhitsya.  Simvoly  raspolagayutsya v odnoj iz pozicij, soot-
vetstvuyushchih  obychnym  strokam i stolbcam, chto oznachaet,  chto  oni
vsegda nachinayutsya na granice kratnoj vos'mi tochkam.





   PCjr i EGA rabotayut s cvetom  sovsem  po-drugomu,  chem cvetnoj
adaptor.   Oni  ispol'zuyut registry paletty, kotorye pozvolyayut  v
lyuboj moment izmenit' cvet,  kotoryj  sootvetstvuet  dannomu kodu
cveta. Vsledstvie etoj raznicy my budem obsuzhdat' eti dve sistemy
otdel'no i nachnem s cvetnogo adaptora.
   Obe sistemy ispol'zuyut  odin  i  tot  zhe  osnovnoj nabor kodov
cveta,  kotoryj v tochnosti sovpadaet s  ispol'zuemym v  tekstovyh
rezhimah:

   Nomer koda            Cepochka bitov         Cvet

      0                     0000             chernyj
      1                     0001             sinij
      2                     0010             zelenyj
      3                     0011             cian
      4                     0100             krasnyj
      5                     0101             magenta
      6                     0110             korichnevyj
      7                     0111             belyj
      8                     1000             seryj
      9                     1001             yarkosinij
      10                    1010             yarkozelenyj
      11                    1011             yarkij cian
      12                    1100             rozovyj
      13                    1101             yarkaya magenta
      14                    1110             zheltyj
      15                    1111             yarkobelyj

   Dlya  cvetnogo  graficheskogo  adaptora  cvet  razreshen tol'ko v
rezhime umerennogo razresheniya. Dlya kazhdoj tochki otvodyatsya dva bita
kazhdogo bajta videobufera. CHetyre vozmozhnyh kombinacii etih bitov
predstavlyayut  odin  fonovyj i tri osnovnyh cveta.   Fonovyj  cvet
mozhet byt' lyubym iz 16. Odnako tri osnovnyh cveta mogut vybirat'-
sya iz odnoj iz dvuh palett, kazhdaya iz kotoryh soderzhit tol'ko tri
predopredelennyh cveta. |to sleduyushchie cveta:

   Nomer koda    Cepochka bitov    Paletta 0    Paletta 1

       0             00           cvet fona    cvet fona
       1             01           zelenyj      cian
       2             10           krasnyj      magenta
       3             11      zheltyj/korichnevyj belyj

Esli Vy v kakoj-to moment  pereklyuchilis'  mezhdu palettami, to vse
vyvedennye na ekran cveta budut sootvetstvenno izmeneny.  Edinst-
vennyj sposob ispol'zovat' cvet, ne  vhodyashchij v eti paletty, sos-
toit v tom, chtoby iskustvenno rassmatrivat' odin iz cvetov palet-
ty kak fonovyj cvet,  chto  predpolagaet  zapolnenie  etim  cvetom
vsego ekrana, kogda ekran chistitsya (ispol'zujte dlya etogo  pryamoe
otobrazhenie v pamyat').  Posle  etogo  istinnyj fonovyj cvet mozhet
pokazyvat'sya  "skvoz'  nego" v kachestve osnovnogo  cveta.   Takaya


tehnika privodit k sozdaniyu granicy  ekrana, analogichnoj toj, chto
izobrazhaetsya  v  tekstovyh rezhimah.  V protivnom  sluchae  granica
ekrana ne mozhet byt' vydelena  cvetom,  tak kak ves' ekran zakra-
shivaetsya fonovym cvetom, hotya tochki otnosyashchiesya k oblasti granicy
nel'zya adresovat'.  Otmetim, chto BIOS hranit v svoej oblasti dan-
nyh odnobajtnuyu peremennuyu, kotoraya soderzhit tekushchij nomer palet-
ty. Ee adres raven  0040:0066H.  Izmenenie  etogo chisla ne menyaet
tekushchuyu ustanovku paletty; naoborot, esli Vy izmenite cvet palet-
ty drugimi sredstvami,  pomimo  funkcij  operacionnoj sistemy, to
znachenie etoj peremennoj budet modificirovano.
   Simvoly mogut peremeshivat'sya s tochechnoj grafikoj.  Cvet, koto-
rym budut vyvodit'sya simvoly,  zavisit  ot togo, kakuyu fuknciyu Vy
budete ispol'zovat' dlya ih vyvoda.  Prostejshaya funkciya po umolcha-
niyu ispol'zuet tretij cvet  tekushchej  paletty.  Odnako imeetsya ryad
sposobov  ispol'zovat' lyuboj iz cvetov paletty, a takzhe  vyvodit'
simvoly razlichnymi cvetami. Smotrite obsuzhdenie v [4.1.3].
   EGA i PCjr obespechivayut  dobavochnuyu  gibkost'  v ispol'zovanii
atributov cveta, nezavisimo ot togo, v kakom rezhime oni rabotayut.
Pri 16-cvetnoj grafike  chetyre  bita,  nahodyashchiesya  v  pamyati dlya
kazhdoj  tochki ekrana dayut cepochku bitov, kotoraya  ne  perevoditsya
pryamo v sootvetstvuyushchie cveta privedennoj  tablicy.  Vmesto etogo
kazhdyj  nomer otnositsya k odnomu iz 16 registrov paletty.  Kazhdyj
iz etih registrov soderzhit cepochku  bitov, sootvetstvuyushchuyu cvetu,
kotoryj  budet  vyvodit'sya na samom dele.  Esli vse 16  registrov
budut soderzhat' 0100, to nezavisimo  ot togo, kakoj atribut budet
pripisan tochke v pamyati, ona budet vyvedena krasnym cvetom.  Zna-
chenie v registre 0  ispol'zuetsya  v  kachestve fonovogo cveta.  Na
ris. 4-1 v [4.1.3] pokazan etot mehanizm.  V dvuh- i chetyrehcvet-
nom rezhimah ispol'zuyutsya  tol'ko  pervye  dva ili chetyre registra
paletty.
   Registry  paletty pozvolyayut programme izmenit' vse vyvodimoe v
odnom cvete na drugoj, ne delaya nikakih  izmenenij v videobufere.
Bolee  togo otdel'nye ob®ekty mogut poyavlyat'sya i ischezat' kak  po
volshebstvu.  |to  delaetsya  izmeneniem  znacheniya, soderzhashchegosya v
registre  paletty, sootvetstvuyushchemu dannomu ob®ektu, na  znachenie
fonovogo cveta.  Naprimer,  predpolozhim,  chto fonovyj cvet chernyj
(0000) i chto ob®ekt vyveden s atributom 1110, tak chto on vyvodit-
sya v tom cvete, kotoryj ukazan v  registre paletty 15 (po umolcha-
niyu znachenie dlya etogo registra zheltyj).  Esli izmenit'  znachenie
registra 15 na 0000 (chernyj fonovyj cvet), to ob®ekt ischeznet. No
na  samom  dele  ob®ekt hranitsya v pamyati, tak kak on  zapisan  s
atributom 1110, a ne s atributom 0000, kak vse tochki fona. Ob®ekt
mozhet byt' sdelan opyat' vidimym, esli izmenit' znachenie  registra
paletty 15 opyat' na  1110.  Ne  obyazatel'no,  chtoby  ischezali vse
zheltye  ob®ekty, poskol'ku nekotorye mogut byt' vyvedeny s drugim
atributom, kotoryj takzhe sootvetstvuet registru paletty, soderzha-
shchemu takzhe zheltyj cvet.
   EGA mozhet ispol'zovat' 6 bitov registra paletty, a ne 4, kogda
k nemu prisoedinen uluchshennyj  cvetnoj  graficheskij displej firmy
IBM. Pri etom stanovyatsya dostupnymi 64 cveta, kodirovka dlya koto-
ryh R'G'B'RGB. R, G i B  sootvetstvuyut  temnym cvetam, a R', G' i
B' - svetlym. Razlichnye kombinacii sozdayut 64 ottenka.  Kak vseg-
da, 111111 sootvetstvuet belomu cvetu, a 000000 - chernomu.  Otme-


tim, chto cherez registry paletty dlya EGA vsegda dostupny 64 cveta,
nezavisimo ot togo, v  kakom  rezhime  on  rabotaet.  Pri rabote v
rezhime 4-cvetnoj grafiki (kak u cvetnogo adaptora) aktivny tol'ko
mladshie 4 registra paletty, no oni mogut soderzhat' lyubye cveta.

   Vysokij uroven'.

   Kogda cvetnoj displej rabotaet v graficheskom rezhime, to Bejsik
obrabatyvaet  operator COLOR po drugomu, chem v tekstovom  rezhime.
Snachala idet fonovyj cvet, v vide  chisla ot 0 do 15, a zatem idet
nomer paletty 0 ili 1.  Naprimer, COLOR 2,1 ustanavlivaet zelenyj
fonovyj cvet (#2)  dlya  vsego  ekrana  i  aktiviziruet palettu 1.
Posle  etogo tri vozmozhnyh osnovnyh cveta ukazyvayutsya ih nomerami
v palette: 1 - cian, 2 - magenta i 3 - belyj (sravnite s operato-
rom  PAINT).  CHtoby vyklyuchit' cvet v rezhime umerennogo razresheniya
napishite SCREEN ,1.  Otmetim,  chto ispol'zovanie tol'ko chernogo i
belogo  cvetov v rezhime umerennogo razresheniya  ne privodit k eko-
nomii pamyati. PCjr ispol'zuet operator COLOR takim obrazom tol'ko
v  rezhime  SCREEN 1.  Dlya rezhimov ot SCREEN 3 do SCREEN 6  format
etogo operatora COLOR osnovnoj,fonovyj.  Pri etom osnovnoj cvet -
eto chislo v diapazone ot 1 do 15 v 16-cvetnom rezhime i ot 1 do  3
- v 4-cvetnom. On ne dolzhen byt' ravnym 0, kotoryj vsegda ispol'-
zuetsya v kachestve fonovogo cveta.
   Imeyutsya special'nye operatory dlya ustanovki registrov paletty:
PALETTE i PALETTE USING. PALETTE ustanavlivaet cvet sootvetstvuyu-
shchij lyubomu atributy.  Naprimer, PALETTE 9,11 privodit k tomu, chto
tochki narisovannye s cvetom paletty  9 (obychno svetlosinij) budut
vyvedeny v cvete 11 (svetlyj cian). CHtoby izmenit' ustanovku vseh
registrov paletty k ih  pervonachal'nomu  znacheniyu, t.e. chtoby re-
gistr 0 soderzhal 0, registr 12 - 12 i t.d.  nado napisat'  prosto
PALETTE. Otmetim,  chto  v  rezhimah  SCREEN  4 i SCREEN 6 registry
paletty inicializiruyutsya takim obrazom, chtoby atributy cvetov 1-3
byli takimi zhe, kak dlya paletty 1 na cvetnom graficheskom displee.
|to delaetsya v celyah sovmestimosti.
   Vse 16 registrov paletty mogut byt' ustanovleny odnim operato-
rom PALETTE USING.  PALETTE  USING  napravlyaet soderzhimoe 16-ele-
mentnogo celogo massiva v registry paletty.  Imeya neskol'ko takih
massivov programma mozhet bystro pereklyuchat'  razlichnye shemy cve-
tov.   Kazhdyj element massiva dolzhen byt' chislom v diapazone ot 0
do 15, ili -1, v  poslednem  sluchae  sootvetstvuyushchij  registr  ne
izmenyaetsya.   Naprimer, dlya obrashcheniya privychnoj shemy cvetov soz-
dajte massiv, v kotorom  ARRAYNAME(0)  =  15, ARRAYNAME(1) = 14 i
t.d.  Zatem napishite PALETTE USING ARRAYNAME(0) i soderzhimoe mas-
siva ARRAYNAME budet peredano v  registry  paletty.  0 indiciruet
nachal'nuyu poziciyu v massive, s kotoroj nado brat' dannye posylae-
mye v registry.  Mogut  ispol'zovat'sya  bolee dlinnye massivy, iz
kotoryh  dannye mogut brat'sya nachinaya s lyuboj tochki, pri  uslovii
chto do konca massiva eshche est' 16 elementov.  PALETTE USING ARRAY-
NAME(12) budet brat' dannye, nachinaya s 12-go bajta massiva. Otme-
tim, chto operator PALETTE USING rabotaet kak v tekstovom, tak i v
graficheskom rezhimah. Vot primer:


100 DEF INT A-Z         'vse peremennye celye
110 DIM SCHEME1(16)     'massiv dlya shemy cvetov #1
120 DIM SCHEME2(16)     'massiv dlya shemy cvetov #2
130 DATA 3,5,9,2,4,12,15,1,6,7,14,13,8,11,10,0
140 DATA 0,11,13,7,1,12,2,5,10,8,14,6,15,4,9,3
150 FOR N = 0 TO 15     'dlya kazhdogo registra paletty
160 READ Q              'prochitat' kod cveta
170 SCHEME1(N) = Q      'i pomestit' ego v massiv
180 NEXT                '
190 FOR N = 0 TO 15     'to zhe samoe so vtorym massivom
200 READ Q              '
210 SCHEME2(N) = Q      '
220 NEXT                '
230 PALETTE USING SCHEME1(0)  'ustanovka registrov
 .
500 PALETTE USING SCHEME2(0)  'menyaem ih posredi programmy

   Srednij uroven'.

   Funkciya  BH preryvaniya 10H ustanavlivaet kak fonovyj cvet, tak
i cveta paletty - no  ne  odnovremenno.  Dlya  ustanovki  fonovogo
cveta  nado pomestit' v BH 0, a zatem kod cveta ot 0 do 15 v  BL.
Dlya ustanovki paletty nado  pomestit'  v  BH 1, a v BL 0 ili 1. V
dannom primere ustanavlivaetsya cvet fona cian i vybiraetsya palet-
ta 0:

;---ustanovka cveta fona i paletty
   MOV  AH,0BH        ;funkciya ustanovki cveta
   MOV  BH,0          ;snachala ustanavlivaem fonovyj cvet
   MOV  BL,3          ;kod ciana
   INT  10H           ;ustanovka cveta
   MOV  BH,1          ;teper' ustanavlivaem palettu
   MOV  BL,1          ;vybiraem palettu 1
   INT  10H           ;ustanavlivaem palettu

   Na PCjr eta funkciya rabotaet tochno  tak zhe v 4-cvetnom rezhime,
ustanavlivaya  registry  1-3 v odnu iz shem  cvetov,  ispol'zuemyh
cvetnym adaptorom. V 2-cvetnom rezhime 0 v BL sootvetstvuet belomu
cvetu, kak cvetu 1, a 1 - chernomu.  |ta funkciya ne vliyaet na naz-
nacheniya, ispol'zuemye v 16-cvetnom rezhime. Odnako vo vseh sluchayah
fonovyj cvet mozhet byt' ustanovlen zasylkoj v BH 0, a v BL - koda
cveta.

   Nizkij uroven'.

   Dlya cvetnogo adaptora  my  mozhem  poluchit'  dostup k "registru
vybora cveta" cherez port 3D9H. V graficheskih rezhimah etot registr
dejstvuet po-drugomu, chem v tekstovyh (opisannyh v [4.1.3]). Bity
0-3 soderzhat informaciyu o fonovom cvete v obychnom formate  (soot-
vetstvenno sinij, zelenyj  ikrasnyj  komponenty i intensivnost').
Bit 5 vybiraet palettu, kogda etot bit raven 0, to paletta  nomer
0.  V graficheskih rezhimah ostal'nye bity ne imeyut znacheniya.  |tot
registr tol'ko dlya zapisi, poetomu Vy dolzhny ukazyvat' informaciyu
i o fonovom cvete i o palette, pri izmenenii lyubogo iz nih.


   MOV  DX,3D9H          ;adres registra vybora cveta
   MOV  AL,00100110B     ;cepochka bitov dlya ciana i paletty 1
   OUT  DX,AL            ;posylaem ee

   Poskol'ku  oni  ispol'zuyut  registry  paletty,  to etot primer
neprimenim  ni  k PCjr ni k EGA.  Dlya nih nado  prosto  zagruzit'
trebuemye znacheniya v eti registry. U PCjr eti registry numeruyutsya
ot 10H do 1FH. Dostup ko vsem registram osushchestvlyaetsya cherez odin
port s adresom 3DAH. Lyuboe novoe znachenie prinimaemoe etim portom
vosprinimaetsya  adresnym registrom.  Poetomu nado poslat' snachala
nomer registra, a zatem kod cveta  dlya etogo registra. CHtoby byt'
uverennym,  chto  port ozhidaet nomer registra  nado  prochitat'  iz
nego. Naprimer, chtoby pomestit'  yarkosinij  cvet (1001) v registr
paletty 2:

;---pomeshchaem kod yarkosinego cveta v registr paletty 2
   MOV  DX,3DAH         ;adres massiva vorot displeya
   IN   AL,DX           ;chitaem iz nego
   MOV  AL,12H          ;nomer registra
   OUT  DX,AL           ;posylaem nomer registra
   MOV  AL,00001001B    ;kod yarkosinego cveta
   OUT  DX,AL           ;posylaem cvet

U EGA adres porta dostupa k registram paletty - 3C0H, a  registry
numeruyutsya ot 00 do  0FH.  Nado  prochitat'  iz  porta  3DAH (a ne
3C0H), chtoby byt' uverennym, chto ozhidaetsya nomer registra.  Kogda
k EGA  prisoedinen  uluchshennyj  cvetnoj  displej  i pereklyuchateli
ustanovleny  sootvetstvuyushchim  obrazom, to v  registry  pomeshchayutsya
6-bitnye znacheniya.





   Vsledstvie  organizacii  graficheskoj informacii v  videobufere
vyvod odnoj tochki podrazumevaet izmenenie otdel'nyh bitov pamyati.
Rezhimy  dvuh,  chetyreh i shestnadcati cvetov  trebuyut,  chtoby  dlya
ustanovki harakteristik  odnoj  tochki  byli  izmeneny odin, dva i
chetyre bita sootvetstvenno. |ti operacii mogut trebovat' ogromno-
go kolichestva processornogo  vremeni,  o  chem svidetel'stvuet to,
chto  bol'shinstvo graficheskogo programmnogo  obespecheniya  rabotaet
ochen'  medlenno.  Tshchatel'noe  obdumyvanie  chasto  pozvolyaet srazu
ustanovit' vse bity odnogo bajta, a ne obrashchat'sya k odnomu i tomu
zhe bajtu 4 ili 8 raz. Imejte eto  vvidu, i ne sledujte slepo pri-
vedennoj zdes' tehnike potochechnogo vyvoda.

   Vysokij uroven'.

   Bejsik  predostavlyaet  operatory PSET i PRESET  dlya  izmeneniya
cveta otdel'noj tochki. |ti imena obrazovany ot PointSET (ustanov-
ka tochki) i PointRESET (sbros tochki). Oni ochen' pohozhi. Za oboimi
dolzhny sledovat' koordinaty  stolbca i stroki, ukazyvaemoj tochki,
zaklyuchennye v skobki.  Otmetim, chto koordinaty sleduyut v  poryadke
x,y - t.e. snachala  idet  stolbec,  a  zatem stroka; etot poryadok
obratnyj  po otnosheniyu k poryadku operatora LOCATE, kotoryj  pozi-
cioniruet tekst na ekrane. PSET(50,80) ili PRESET(50,80) ustanav-
livayut  cvet tochki v stolbce 50 i stroke 80.  Za operatorom  PSET
mozhet sledovat' kod cveta,  kotoryj lezhit v diapazone, opredelyae-
mom tekushchim rezhimom ekrana.  Esli kod cveta ne ukazan, to ispol'-
zuetsya maksimal'nyj  nomer  koda,  kotoryj  dopustim  dlya dannogo
rezhima. V PRESET cvet ne ukazyvaetsya.  On vsegda vozvrashchaet tochke
cvet fona (kod 0). Naprimer:

100 PSET(100,180),3   'ustanovka cveta 3 tekushchej paletty
110 PRESET(100,180)   'izmenenie cveta tochki na fonovyj

   PSET i PRESET obychno  ispol'zuyut  sistemu koordinat, v kotoroj
levyj  verhnij ugol ekrana imeet koordinaty 0,0.  Operator WINDOW
pozvolyaet Vam pereopredelit' sistemu koordinat tak, chto naprimer,
koordinaty  levogo verhnego ugla budut -100,100, centra ekrana  -
0,0, a pravogo nizhnego ugla  -  100,-100.  Dlya  etogo sluchaya nado
zapisat'  operator  v vide  WINDOW(-100,100)-(100,-100).   (Novye
koordinaty ne budut  vliyat'  na   sistemu  koordinat  25*80  (ili
25*40), v kotoroj operator LOCATE pozicioniruet simvoly na grafi-
cheskom ekrane [4.2.1].)
   Kak i v operatore  LINE  [4.4.5],  pervoe  chislo kazhdoj pary v
skobkah ukazyvaet gorizontal'nuyu koordinatu (po osi x). Koordina-
ty mogut byt' kak  polozhitel'nymi,  tak i otricatel'nymi, lish' by
oni  ne  byli ravnymi.  Levomu krayu ekrana  vsegda  prisvaivaetsya
men'shee chislo (kotoroe mozhet byt'  bol'shim otricatel'nym).  Takim
obrazom,  dazhe esli Vy pomenyaete koordinaty v primere i  zapishete
operator   WINDOW(100,-100)-(-100,100),   to  znachenie -100 budet
vzyato dlya levoj granicy ekrana.


   Vtoroe  chislo kazhdoj pary koordinat opredelyaet granicy  ekrana
po vertikali. I opyat', men'shee znachenie budet otnosit'sya k nizhnej
granice  ekrana,  nezavisimo ot togo, v kakoj pare koordinat  ono
ukazano.  Bol'shee  polozhitel'noe  znachenie  (ili  men'shee iz dvuh
otricatel'nyh) prisvaivaetsya v kachestve znacheniya osi y dlya  verh-
nej stroki ekrana.  Napravlenie  uvelicheniya  znachenij  mozhet byt'
obrashcheno, s tem chtoby maksimal'nye znacheniya sootvetstvovali  nizu
ekrana i naoborot. Nado prosto dobavit' k operatoru slovo SCREEN,
naprimer, WINDOW SCREEN(-100,100)-(100,-100).
   Programma  mozhet  ukazyvat'  tochki, otnosyashchiesya k  oblasti  za
predelami koordinat  ekrana.   Naprimer,  centr  okruzhnosti mozhet
nahodit'sya  za  predelami ekrana, s tem chtoby vidna  byla  tol'ko
chast' dugi.  Otmetim, chto koordinaty, ukazyvaemye operatorom WIN-
DOW  mogut nepreryvno izmenyat'sya pri izmenenii masshtaba ili  ugla
zreniya na ob®ekt. Izobrazhenie  dolzhno  pererisovyvat'sya, a inogda
stirat'sya, pri izmenenii koordinat okna.
   Operator  PMAP  preobrazuet koordinaty ot  obychnoj  fizicheskoj
sistemy koordinat k "mirovoj" sisteme, ustanavlivaemoj operatorom
WINDOW. PMAP ispol'zuet chetyre kodovyh nomera:

   0         preobrazuet x iz "mirovoj" sistemy v fizicheskuyu
   1         preobrazuet y iz "mirovoj" sistemy v fizicheskuyu
   2         preobrazuet x iz fizicheskoj sistemy v "mirovuyu"
   3         preobrazuet y iz fizicheskoj sistemy v "mirovuyu"

Operator  imeet formu PMAP(poziciya,kod).  Naprimer,  predpolozhim,
chto Vy ustanovili sistemu  "mirovyh" koordinat operatorom WINDOW.
Koordinaty  levogo  verhnego  ugla ekrana  (-100,100), a  pravogo
nizhnego - (100,-100). Kakaya budet poziciya central'noj tochki ekra-
na (0,0) pri ispol'zovanii obychnoj fizicheskoj sistemy 320*200,  v
kotoroj levyj verhnij  ugol  imeet  koordinaty 0,0? CHtoby najti X
napishite X = PMAP(0,0), a Y - napishite Y = PMAP(0,1). Vy poluchite
znachenie X = 160, a Y = 100.

   Srednij uroven'.

   Funkciya CH preryvaniya 10H  ustanavlivaet  tochku.   DX soderzhit
stroku,  a CX - stolbec, oba otschityvaemye ot 0.  Kod cveta pome-
shchaetsya v AL.  Otmetim, chto  soderzhimoe AX budet razrusheno pri vy-
polnenii preryvaniya.  Esli Vy ispol'zuete eto preryvanie v cikle,
to ne zabud'te sohranit' AX na steke i kazhdyj raz vosstanavlivat'
ego.

;---vyvod tochki s koordinatami 100,180
   MOV  AH,0CH        ;funkciya ustanovki tochki
   MOV  AL,3          ;vybiraem cvet 3 paletty
   MOV  CX,100        ;stroka
   MOV  DX,180        ;stolbec
   INT  10H           ;vyvodim tochku
;---stiraem tochku
   MOV  AH,0CH        ;vosstanavlivaem funkciyu
   MOV  AL,0          ;ispol'zuem dlya stiraniya fonovyj cvet
   MOV  DX,100        ;stroka
   MOV  CX,180        ;stolbec
   INT  10H           ;stiraem tochku


   V  to  vremya kak cvet paletty pomeshchaetsya v  mladshie  bity  AL,
starshij bit takzhe imeet znachenie.  Esli on raven 1, to nad cvetom
proizvoditsya  operaciya isklyuchayushchego ILI s tekushchim cvetom.  Napom-
nim, chto operaciya isklyuchayushchego ILI ustanavlivaet bit tol'ko v tom
sluchae  esli iz dvuh sravnivaemyh bitov ustanovlen  tol'ko  odin.
Esli oba sravnivaemye bita ravny  1 ili oba ravny 0, to rezul'tat
budet 0. Dlya dvuhcvetnogo rezhima eto oznachaet, chto takaya operaciya
obrashchaet ustanovku  bita.  Esli  etu  operaciyu  primenit' ko vsem
tochkam ekrana, to budet obrashchen ves' ekran. V chetyreh- i 16-cvet-
nom rezhimah, s drugoj storony,  oblasti  ekrana mogut menyat' svoi
cveta.  Naprimer, pust' v 4-cvetnom rezhime umerennogo  razresheniya
oblast' zanyata tochkami libo cveta 1 paletty (ustanovka bitov 01B)
ili cveta 2 paletty (10B). CHto proizojdet, esli primenit' ko vsem
tochkam etoj oblasti operaciyu isklyuchayushchego ILI s 11B? 01B perejdet
v 10B, a 10B perejdet v 01B - cveta budut obrashcheny.

   Nizkij uroven'.

   Na nizkom urovne my imeem vozmozhnost' pryamogo dostupa k video-
buferu (otobrazhenie v pamyat'). Snachala Vy dolzhny vychislit' smeshche-
nie tochki (a) vnutri bufera i (b) vnutri bajta, soderzhashchego bity,
otnosyashchiesya k dannoj tochke.  Posle etogo bitovye operacii obespe-
chat sootvetstvuyushchuyu ustanovku.   Otmetim, chto esli Vy stanete is-
pol'zovat'  etu  tehniku  na PCjr, kogda on rabotaet v  odnom  iz
16-cvetnyh rezhimov, ispol'zuyushchih stranicu  razmerom 32K, to vyvod
v  adresa, nachinayushchiesya s paragrafa B800H ne budet  perenapravlen
verno.  Vam neobhodimo pryamo adresovat' real'nye yachejki, raspolo-
zhennye v segmente nizhe 2000H.
   Dlya  nahozhdeniya tochki neobhodimo prezhde vsego opredelit' naho-
ditsya li ona v chetnoj ili nechetnoj stroke. V dannom primere stro-
ka pomeshchena v CX, a stolbec - v DX.  Esli bit 0 registra CX raven
0, to stroka imeet chetnyj  nomer.   CHetnye  stroki raspolozheny so
smeshcheniem  0  otnositel'no nachala bufera.  Esli zhe  stroka  imeet
nechetnyj nomer, to neobhodimo  dobavit' smeshchenie 2000H dlya ukaza-
niya na nachalo vtoroj poloviny bufera.
   Zatem razdelite nomer stroki na 2, neobhodimo podschitat' chislo
tol'ko chetnyh ili nechetnyh strok i umnozh'te rezul'tat na 80, t.k.
na odnu stroku rashoduetsya 80 bajt.  Dlya deleniya mozhno  ispol'zo-
vat' instrukciyu SHL, a rezul'tat  dast obshchee chislo bajtov vo vseh
strokah,  predshestvuyushchih  stroke, v kotoroj  raspolozhena  iskomaya
tochka.
   Vmesto togo, chtoby  zatem  vychislyat'  chislo stolbcov v tekushchej
stroke,  luchshe  snachala  opredelit' poziciyu pary  bitov v  bajte,
kotorye soderzhat etu tochku. |to dostigaetsya obrashcheniem vseh bitov
v nomere stolbca (posle togo kak sohranena ego kopiya) i vydeleniya
dvuh mladshih bitov.  |ta procedura pokazhet nahodyatsya li dva bita,
otnosyashchiesya  k  tochke  na pervoj, vtoroj, tret'ej  ili  chetvertoj
pozicii v bajte.  Umnozhiv eto  znachenie  na 2 my poluchaem nomer v
bajte pervogo iz dvuh bitov, otnosyashchihsya k dannoj tochke.
   Zatem  prihodit vremya podschitat' chislo bajtov v stroke,  pred-
shestvuyushchih bajtu, soderzhashchemu itnformaciyu  o trebuemoj tochke. Dlya
rezhima umerennogo razresheniya nado razdelit' chislo stolbcov na  4,
a dlya vysokogo razresheniya - na  8.   Posle etogo nado slozhit' tri
smeshcheniya:  smeshchenie za schet nomera stroki, za schet nomera stolbca
i smeshchenie nachala chetnyh/nechetnyh  strok v bufere. Posle etogo Vy
mozhete poluchit' trebuemyj bajt iz bufera.


   Nakonec, nado proizvesti operaciyu nad sootvetstvuyushchimi  bitami
bajta. Vrashchajte bajt do  teh  por,  poka para bitov otnosyashchihsya k
tochke  ne stanet mladshimi.  Pri vrashchenii neobhodimo  ispol'zovat'
ranee podschitannoe znachenie  pozicii  bitov.  Zatem vyklyuchite oba
bita pomestite v nih instrukciej OR trebuemyj kod paletty.  Zatem
nado proizvesti obratnoe vrashchenie i poslat' bajt obratno v bufer.

;---v segmente dannyh
PALETTE_COLOR  DB   2

;---vyzov procedury
   MOV  AX,0B800H         ;ukazyvaem na videobufer
   MOV  ES,AX             ;
   MOV  CX,100            ;nomer stroki
   MOV  DX,180            ;nomer stolbca
   CALL SET_DOT           ;
    .
    .
;---opredelyaem chislo bajtov v predshestvuyushchih strokah
SET_DOT     PROC
            TEST CL,1              ;nomer stroki nechetnyj?
            JZ   EVEN_ROW          ;esli net, to vpered
            MOV  BX,2000H          ;smeshchenie dlya nechetnyh strok
            JMP  SHORT CONTINUE    ;perehod vpered
EVEN_ROW:   MOV  BX,0              ;smeshchenie dlya chetnyh strok
CONTINUE:   SHR  CX,1              ;delim chislo strok na 2
            MOV  AL,80             ;umnozhaem na 80
            MUL  CL                ;v AX - chislo bajtov
;---opredelyaem polozhenie pary bit v bajte
            MOV  CX,DX             ;kopiruem nomer stolbca
            NOT  CL                ;obrashchaem bity
            AND  CL,00000011B      ;v CL - poziciya bitov (0-3)
            SHL  CL,1              ;poziciya pervogo bita pary
;---podschityvaem smeshchenie stolbca v bajtah
            SHR  DX,1              ;delim nomer stolbca na 4
            SHR  DX,1              ;(nuzhny dva mladshih bita)
;---vychislyaem smeshchenie dlya izmenyaemogo bajta
            ADD  AX,DX             ;skladyvaem vse tri smeshcheniya
            ADD  BX,AX             ;
;---izmenyaem bity nuzhnogo bajta
            MOV  AH,ES:[BX]        ;chitaem nuzhnyj bajt
            ROR  AH,CL             ;sdvigaem nuzhnye bity vniz
            AND  AH,11111100B      ;chistim mladshie 2 bita
            MOV  AL,PALETTE_COLOR  ;izmenyaem ih na cvet paletty
            OR   AH,AL             ;
            ROL  AH,CL             ;obratnoe vrashchenie
            MOV  ES:[BX],AH        ;vozvrashchaem bajt
            RET                    ;
SET_DOT     ENDP





   U EGA grafika bolee slozhnaya. S  tochki zreniya processora rezhimy
ekrana 0-7 dejstvuyut tak zhe, kak sootvetstvuyushchie rezhimy dlya cvet-
nogo adaptora ili PCjr, no rezhimy ot DH do 10H sovershenno drugie.
Organizaciya  pamyati  dlya etih rezhimov menyaetsya, v zavisimosti  ot
chisla ispol'zuemyh cvetov i kolichestva pamyati, imeyushchejsya na plate
displeya. Smotrite ris. 4-4 v [4.4.0].
   V  rezhimah D, E i 10H pamyat' razbita na 4  bitovye  ploskosti.
Kazhdaya ploskost' organizovana takim zhe obrazom, kak dlya cherno-be-
logo rezhima vysokogo razresheniya cvetnogo adaptora, kotoryj obsuzh-
dalsya v [4.4.2]:  kogda  bajt  dannyh  posylaetsya  v opredelennyj
adres  videobufera, to kazhdyj bit sootvetstvuet tochke na  ekrane,
prichem ves' bajt sootvetstvuet  gorizontal'nomu segmentu linii, a
bit  7 sootvetstvuet samoj levoj tochke.  Vyvodyatsya  chetyre  takih
bitovyh ploskosti, otnosyashchiesya k  odnim i tem zhe adresam v video-
bufere. |to privodit k tomu, chto kazhdaya tochka opisyvaetsya chetyr'-
mya bitami (davaya 16 cvetov), prichem kazhdyj bit nahoditsya votdel'-
nom bajte otdel'noj bitovoj ploskosti.
   No  kak Vy mozhete zapisat' 4 razlichnyh bajta dannyh,  raspolo-
zhennyh po odnomu i tomu zhe adresu? Otvet na etot vopros sostoit v
tom,  chto  Vy ne posylaete posledovatel'no chetyre bajta po  etomu
adresu.  Vmesto etogo odin iz treh rezhimov zapisi pozvolyaet izme-
nit' vse 4 bajta, na osnovanii odnogo bajta dannyh poluchennogo ot
processora. Vliyanie dannyh poslannyh processorom zavisit ot usta-
novki  neskol'kih registrov, vklyuchayushchih dva registra maski, koto-
rye opredelyayut na kakie bity i  v  kakih bitovyh ploskostyah budut
izmenyat'sya bity.
   Dlya  ponimaniya etih registrov my dolzhny snachala razobrat'sya  s
chetyr'mya registrami zadvizhki (latch register).  Oni soderzhat dan-
nye dlya chetyreh bitovyh ploskostej v toj pozicii, k kotoroj  bylo
poslednee obrashchenie. (Zametim,  chto  termin bitovaya ploskost' is-
pol'zuetsya kak dlya celoj oblasti videobufera, tak i dlya odnobajt-
nogo bufera,  vremenno  hranyashchegosya  v  registre zadvizhki.) Kogda
processor  posylaet dannye po opredelennomu adresu, to eti dannye
mogut izmenit' ili polnost'yu smenit'  dannye registra zadvizhki, a
vposledstvii  imenno dannye iz registra zadvizhki  zapisyvayutsya  v
videobufer. Kakim  obrazom  dannye  processora  vliyayut na registr
zadvizhki zavisit ot ispol'zuemogo rezhima zapisi, a takzhe ot usta-
novki nekotoryh drugih registrov. Pri chtenii adresa iz videobufe-
ra  registry  zadvizhki zapolnyayutsya chetyr'mya  bajtami  iz  chetyreh
bitovyh ploskostej po dannomu adresu.   Registrami zadvizhki legko
manipulirovat',  proizvodya  ih  soderzhimym  razlichnye  logicheskie
operacii, chto pozvolyaet ustraivat' razlichnye graficheskie tryuki.
   Registr maski bitov i registr maski karty dejstvuyut na regist-
ry  zadvizhki, zashchishchaya opredelennye bity ili bitovye ploskosti  ot
izmeneniya pod dejstviem dannyh,  postupayushchih  ot processora.  Re-
gistr  maski  bitov  eto registr tol'ko dlya zapisi,  adres  porta
kotorogo 3CFH.  Snachala nado poslat' 8 v port 3CEH, chtoby ukazat'
na etot registr. Ustanovka bita etogo registra v 1 maskiruet etot
bit vo vseh chetyreh  bitovyh  ploskostyah,  delaya  sootvetstvuyushchuyu
tochku  nedostupnoj dlya izmeneniya.  Odnako, poskol'ku oborudovanie
rabotaet  v  bajtovyh  terminah, to real'no  "neizmenyaemye"  bity
perezapisyvayutsya v  chetyre  bitovye  ploskosti.  Dannye  dlya etih
maskiruemyh bitov hranyatsya v registrah zadvizhki, poetomu program-


ma dolzhna byt' uverena, chto tekushchee soderzhimoe registrov zadvizhki
otnositsya  k  pravil'nomu adresu pamyati.  Po etoj  prichine  pered
zapis'yu po dannomu adresu nado schityvat' iz nego.
   Registr maski karty imeet adres porta 3C5H. |tot registr tol'-
ko dlya zapisi. Pered posylkoj dannyh nado poslat' po etomu adresu
2 kak ukazatel'. Bity 0-3  etogo  registra  sootvetstvuyut bitovym
ploskostyam  0-3; starshie 4 bita registra ne ispol'zuyutsya.   Kogda
bity 0-3 ravny 0, to  sotvetstvuyushchie  bitovye  ploskosti ne izme-
nyayutsya pri operaciyah zapisi. |to svojstvo ispol'zuetsya po-raznomu
v razlichnyh rezhimah zapisi, kak Vy uvidite v dal'nejshem.
   Tri rezhima zapisi  ustanavlivayutsya  registrom  rezhima, kotoryj
yavlyaetsya  registrom  tol'ko dlya zapisi, a adres  porta  dlya  nego
3CFH, kotoryj  indeksiruetsya  predvaritel'noj  zasylkoj  5 v etot
port.  Rezhim zapisi ustanavlivaetsya v bitah 0 i 1, kak chislo ot 0
do 2.  Bit 2 dolzhen byt' ravnym  0, tak zhe kak i bity 4-7.  Bit 3
ustanavlivaet  odin iz dvuh rezhimov chteniya iz videobufera.   |tot
bit mozhet byt' 0 ili 1. BIOS EGA ustanavlivaet rezhim zapisi v 00.

   Rezhim zapisi 0:
   V prostejshem sluchae rezhim zapisi  0 kopiruet dannye processora
v kazhduyu iz chetyreh bitovyh ploskostej.  Naprimer, pust' po opre-
delennomu adresu videobufera  poslano  11111111B  i razresheny vse
bity i vse bitovye ploskosti (t.e. nichto ne maskirovano opisanny-
mi vyshe registrami masok). Togda kazhdyj bit vo vseh chetyreh plos-
kostyah budet ustanovlen v 1, tak chto cepochka bitov dlya kazhdoj  iz
sootvetstvuyushchih tochek  budet  1111B.   |to  oznachaet, chto 8 tochek
budut vyvedeny v cvete 15, kotoryj iznachal'no sootvetstvuet yarko-
belomu cvetu, hotya  registry  paletty  pozvolyayut,  chtoby na samom
dele eto byl lyuboj iz dopustimyh cvetov.
   Teper'  rassmotrim  tot  zhe  sluchaj,  no  posylaetsya  znachenie
00001000B. Cepochka bitov dlya  tochki 3 budet 1111, a dlya ostal'nyh
- 0000, chto sootvetstvuet chernomu (iznachal'no).  Poetomu v dannom
sluchae tol'ko tochka 3 poyavitsya na ekrane (yarkobelaya), a ostal'nye
7  tochek budut vyklyucheny.  Dazhe esli ostal'nye 7 tochek pered etim
vyvodilis' v kakom-to cvete, to teper'  vse oni budut pereklyucheny
na 0000.
   Teper'  rassmotrim drugie cveta, krome 1111B.  Esli Vy poshlete
kod paletty zhelaemogo cveta  v  registr  maski  karty, to registr
maskiruet opredelennye bitovye ploskosti takim obrazom, chto budet
vosproizveden trebuemyj  cvet.  Naprimer,  esli  Vy hotite cvet s
kodom 0100, to poshlite 0100 v registr maski karty.  Togda bitovye
ploskosti 0, 1 i 3 ne budut izmenyat'sya.  Kogda Vy poshlete po nuzh-
nomu  adresu 11111111B, to eto znachenie budet pomeshcheno  tol'ko  v
bitovuyu ploskost' 2 i cepochka  bitov dlya kazhdoj tochki budet 0100.
Esli Vy poshlete po etomu adresu 00001000B, to tochka 3 budet imet'
cepochku bitov 0100, a ostal'nye tochki - 0000.
   Imeetsya, odnako, odna slozhnost'. Registr maski karty zapreshchaet
izmenenie bitovyh ploskostej, no ne obnulyaet ih. Predpolozhim, chto
bitovaya ploskost' 0 byla zapolnena edinicami, a bitovye ploskosti
1  i 3 byli zapolneny nulyami.  Esli Vy zapretite izmeneniya v etih
treh ploskostyah, a zatem poshlete 11111111B po opredelennomu adre-
su,  to bitovaya ploskost' 2 budet zapolnena 11111111B, a  bitovaya
ploskost' 0 sohranit  svoi  edinicy,  poetomu  rezul'tiruyushchij kod
cveta  kazhdoj tochki stanet 0101B.  Vstrechayutsya sluchai, kogda  eto
svojstvo mozhno ispol'zovat' dlya izmeneniya cvetov ekrana. No voob-


shche govorya, neobhodimo ochishchat'  vse chetyre bitovye ploskosti (t.e.
vse  chetyre  registra zadvizhki) pered tem, kak pisat' tuda  lyubye
cveta krome 1111B ili 0000B.   |to  delaetsya prosto posylkoj 0 po
ukazannomu  adresu.  Neobhodimo chtoby pri etom byla razreshena za-
pis' vo vse chetyre bitovye ploskosti.
   Vysheprivedennoe  obsuzhdenie   kasalos'  odnovremennogo  vyvoda
vos'mi tochek.  Nu a kak vyvesti men'shee kolichestvo tochek? V  etom
sluchae, konechno,  neobhodimo  sohranit'  sushchestvuyushchie  dannye dlya
nekotoryh  tochek,  a chtoby eto bylo vozmozhno  tekushchee  soderzhimoe
dannogo adresa sohranyaetsya v  registrah  zadvizhki.  Zatem ispol'-
zuetsya registr maski bitov dlya maskirovaniya teh tochek, kotorye ne
dolzhny izmenyat'sya. Esli bit etogo registra sbroshen v 0, to dannye
poluchaemye ot processora dlya etogo bita ignoriruyutsya i vmesto nih
ispol'zuyutsya dannye, hranyashchiesya  v  registrah  zadvizhki. Raven li
etot bit v dannyh processora 0 ili 1 - ne imeet znacheniya; esli Vy
izmenyaete tol'ko bit 2, a vse  ostal'nye  maskirovany, to dannye,
kotorye  prihodyat ot processora mogut byt' 0FFH ili 4H, ili lyuboe
drugoe znachenie, dlya kotorogo bit  2 ustanovlen. Esli bit 2 s'ro-
shen,  to 0 pomeshchaetsya v etoj pozicii vo vseh razreshennyh  bitovyh
ploskostyah.
   Voobshche govorya, programma dolzhna  snachala prochitat' lyubuyu yachej-
ku, v kotoruyu ona sobiraetsya zapisat' men'she chem 8 tochek. Imeyutsya
dva rezhima chteniya (obsuzhdaemye v [4.4.4])  i bezrazlichno kakoj iz
nih vybran.  Operaciya chteniya zagruzhaet registry zadvizhki chetyr'mya
bajtami dannyh dlya dannogo  adresa  pamyati.  Dannye, vozvrashchaemye
processoru operaciej chteniya, mogut byt' otbrosheny.
   Do  sih por byli rassmotreny samye prostye vozmozhnosti  rezhima
zapisi 0. Pri  zhelanii  Vy  mozhete  delat'  namnogo bolee slozhnye
manipulyacii. Odna iz vozmozhnostej sostoit v modifikacii registrov
zadvizhki s pomoshch'yu logicheskih operacij pered zapis'yu.  Dlya reali-
zacii etoj vozmozhnosti registr vrashcheniya dannyh ispol'zuet sleduyu-
shchie bity:

   bity 2-0        chislo vrashchenij
        4-3        00     dannye ne modificiruyutsya
                   01     logicheskoe I s registrom zadvizhki
                   10     logicheskoe ILI s registrom zadvizhki
                   11     isklyuchayushchee ILI s registrom zadvizhki
        7-5        ne ispol'zuyutsya

   CHislo  vrashchenij,  kotoroe  mozhet  byt'  ot  0 do 7, pokazyvaet
skol'ko bitov dannyh dolzhny vrashchat'sya pered tem, kak pomestit' ih
v registr zadvizhki.  Obychno eto znachenie ravno nulyu.  Analogichno,
bity 4-3, kak pravilo ravny 00, krome sluchaev, kogda proizvodyatsya
logicheskie operacii. Za schet  manipulyacij s etim registrom odni i
te  zhe dannye mogut davat' razlichnye cveta i izobrazheniya bez  do-
polnitel'noj  processornoj  obrabotki.   Registr  vrashcheniya dannyh
indeksiruetsya  posylkoj 3 v port 3CEH; zatem dannye posylayutsya  v
3CFH.
   Nakonec, rezhim zapisi 0 mozhet  rabotat' sovsem po-drugomu esli
razresheny  ustanovka/sbros.  V etom sluchae opredelennye  cveta  v
mladshih chetyreh bitah  registra  ustanovki/sbrosa  (kotoryj  tozhe
imeet adres porta 3CFH, a indeksiruetsya posylkoj 0 v 3CEH).  Ime-
etsya sootvetstvuyushchij registr razresheniya ustanovki/sbrosa, kotoryj
razreshaet  lyuboj iz etih chetyreh bitov, ustanavlivaya svoi mladshie


bity v 1. Kogda vse 4 bita v registre ustanovki/sbrosa razresheny,
to oni pomeshchayutsya vo vse 8 adresov bitovoj ploskosti pri  poluche-
nii dannyh ot processora, pri  etom sami dannye processora otbra-
syvayutsya.  Esli razresheny ne vse bity ustanovki/sbrosa, to dannye
processora pomeshchayutsya dlya zapreshchennyh tochek. Otmetim, chto registr
maski bitov zapreshchaet zapis' dannyh ustanovki/sbrosa v opredelen-
nye tochki, no  ustanovka  registra  maski  karty ignoriruetsya pri
ispol'zovanii ustanovki/sbrosa.  BIOS inicializiruet registr raz-
resheniya ustanovki/sbrosa v  0,  tak  chto  on neaktiven. Ego adres
porta 3CFH, a indeksiruetsya on posylkoj 1 v port 3CEH.

Rezhim zapisi 1:
   Rezhim zapisi 1 prednaznachen dlya special'nyh prilozhenij. V etom
rezhime tekushchee soderzhimoe  registra zadvizhki zapisyvaetsya po uka-
zannomu  adresu.  Napominaem, chto registry  zadvizhki  zapolnyayutsya
operaciej chteniya.  |tot rezhim ochen' polezen dlya bystrogo perenosa
dannyh pri operaciyah sdviga ekrana. Registr maski bitov i registr
maski  karty ne vliyayut na etu operaciyu.  Ne imeet takzhe  znacheniya
kakie dannye posylaet processor  -  soderzhimoe registrov zadvizhki
zapisyvaetsya v pamyat' bez izmenenij.

Rezhim zapisi 2:
   Rezhim  zapisi 2 predostavlyaet al'ternativnyj sposob  ustanovki
otdel'nyh tochek.  Processor posylaet dannye, u kotoryh imeyut zna-
chenie  tol'ko  4 mladshih bita, kotorye rassmatrivayutsya  kak  cvet
(indeks registra paletty).  Mozhno  skazat', chto eta cepochka bitov
vstavlyaetsya  poperek bitovyh ploskostej.  Cepochka dubliruetsya  na
vse vosem' tochek, otnosyashchihsya k  dannomu  adresu, do teh por poka
registr maski bitov ne predohranyaet opredelennye tochki ot izmene-
niya. Registr maski karty aktiven, kak i v rezhime zapisi 0. Konech-
no processor dolzhen poslat' polnyj bajt, no tol'ko mladshie 4 bita
sushchestvenny.

   Vysokij uroven'.

   Bejsik podderzhivaet EGA v tradicionnyh rezhimah cvetnogo grafi-
cheskogo adaptora. Ko vremeni vyhoda etoj knigi podderzhki dopolni-
tel'nyh rezhimov EGA ne  sushchestvovalo.  Poetomu  u Vas net drugogo
vyhoda,  krome kak ispol'zovat' pryamoe otobrazhenie v  videobufer,
kotoryj nachinaetsya s  adresa  A000:0000.  Samaya  tyazhelaya problema
sostoit  v ustanovke rezhima displeya.  Dlya ee resheniya  ispol'zujte
sleduyushchuyu proceduru na mashinnom yazyke:

10 S$ = CHR$(&H2A)+CHR$(&HE4)+CHR$(&HB0)+CHR$(&H0D)
        +CHR$(&HCD)+CHR$(&H10)+CHR$(&HCB)
20 DEF SEG                  'ustanovka segmenta
30 Y = VARPTR(S$)           'ukazatel' na stroku
40 Z = PEEK(Y+1)+PEEK(Y+2)*256  'vychislenie adresa stroki
50 CALL Z                   'vyzov procedury

CHetvertyj bajt S$ soderzhit nomer rezhima, v dannom sluchae rezhim D.
Vy mozhete vybrat' drugoj rezhim.   V  prilozhenii G ob®yasnyaetsya kak
eta  procedura rabotaet v Bejsike.  Ona polnost'yu zavershennaya, ne
nuzhno nikakoj pobochnoj pamyati,  v  kotoroj soderzhalsya by mashinnyj
kod.   Ne  zabud'te vosstanovit' rezhim displeya  posle  zaversheniya
svoih manipulyacij.


   Zatem nado ustanovit'  sootvetstvuyushchij  rezhim  zapisi. Vot kak
ustanavlivaetsya rezhim zapisi 2:

50 OUT &H3CE,5         'indeksiruem registr rezhima zapisi
60 OUT &H3CF,2         'vybiraem rezhim 2

Rezhim  zapisi  takzhe dolzhen byt'  vosstanovlen  posle  zaversheniya
programmy.
   Nakonec, privedem obrazcy koda, realizuyushchie pryamoe otobrazhenie
v videobufer:

Rezhim zapisi 0:

100 'risuem krasnuyu tochku v levom verhnem uglu ekrana
110 DEF SEG = &HA000     'ukazyvaem na videobufer
120 OUT &H3CE,8          'adresuem registr maski bitov
130 OUT &H3CF,128        'maskiruem vse bity, krome sed'mogo
140 X = PEEK(0)          'chitaem tekushchee znachenie v zadvizhku
150 POKE 0,0             'chistim
160 OUT &H3C4,2          'adresuem registr maski karty
170 OUT &H3C5,4          'ustanavlivaem krasnyj cvet
180 POKE 0,&HFF          'risuem tochku

Rezhim zapisi 1:

100 'kopiruem verhnyuyu strochku tochek v sleduyushchuyu
110 DEF SEG = &HA000     'ukazyvaem na videobufer
120 FOR N = 0 TO 79      'dlya vseh 80 bajtov stroki
130 X = PEEK(N)          'zapolnyaem zadvizhki
140 POKE N+80,Y          'kopiruem v sleduyushchuyu stroku
150 NEXT                 'perehodim k sleduyushchemu segmentu

Rezhim zapisi 2:

100 'risuem krasnuyu tochku v levom verhnem uglu ekrana
110 DEF SEG = &HA000     'ukazyvaem na videobufer
120 OUT &H3CE,8          'adresuem registr maski bitov
130 OUT &H3CF,128        'maskiruem vse bity, krome sed'mogo
140 X = PEEK(0)          'chitaem tekushchee znachenie v zadvizhku
150 POKE 0,4             'posylaem krasnyj cvet

   Srednij uroven'.

   EGA podderzhivaet standartnye graficheskie funkcii BIOS.   Mozhno
vyvesti tochku s pomoshch'yu funkcii CH preryvaniya 10H, tak zhe kak dlya
cvetnogo  displeya ili PCjr.  Pri vhode DX dolzhen soderzhat'  nomer
stroki, a CX - nomer stolbca, i  to  i drugoe otschityvaetsya ot 0.
Kod cveta pomeshchaetsya v AL.  Soderzhimoe AX menyaetsya pri vypolnenii
preryvaniya.

;---risuem tochku po adresu 50,100
   MOV  AH,0CH        ;funkciya vyvoda tochki
   MOV  AL,12         ;vybiraem registr paletty 12
   MOV  CX,100        ;nomer stroki
   MOV  DX,50         ;nomer stolbca
   INT  10H           ;risuem tochku


   Nizkij uroven'.

   Nizhe privedeny primery dlya  treh  rezhimov zapisi. Pered ih is-
pol'zovaniem  neobhodimo  ustanovit' rezhim displeya,  ispol'zuyushchij
videobufer s adresa A000:0000. Dlya etogo mozhno ispol'zovat' stan-
dartnuyu funkciyu BIOS, naprimer, dlya ustanovki rezhima D:

   MOV  AH,0       ;funkciya ustanovki rezhima
   MOV  AL,0DH     ;vybiraem rezhim D
   INT  10H        ;ustanavlivaem rezhim

Ne zabud'te vosstanovit' rezhim pered zaversheniem programmy. Krome
togo, Vam neobhodimo ustanovit' trebuemyj  rezhim zapisi. Vot pri-
mer ustanovki rezhima zapisi 2:

   MOV  DX,3CEH    ;ukazyvaem na registr adresa
   MOV  AL,5       ;inedksiruem registr 5
   OUT  DX,AL      ;posylaem indeks
   INC  DX         ;ukazyvaem na registr rezhima
   MOV  AL,2       ;vybiraem rezhim zapisi 2
   OUT  DX,AL      ;ustanavlivaem rezhim

   I, nakonec, primery treh rezhimov zapisi:

Rezhim zapisi 0:

;---risuem krasnuyu tochku v levom verhnem uglu ekrana
   MOV  AX,0A000H      ;ukazyvaem na videobufer
   MOV  ES,AX          ;
   MOV  BX,0           ;ukazyvaem na pervyj bajt bufera
;---maskiruem vse bity, krome sed'mogo
   MOV  DX,3CEH        ;ukazyvaem na adresnyj registr
   MOV  AL,8           ;nomer registra
   OUT  DX,AL          ;posylaem ego
   INC  DX             ;ukazyvaem na registr dannyh
   MOV  AL,10000000B   ;maska
   OUT  DX,AL          ;posylaem dannye
;---chistim tekushchee soderzhimoe zadvizhki
   MOV  AL,ES:[BX]     ;chitaem soderzhimoe v zadvizhku
   MOV  AL,0           ;gotovimsya k ochistke
   MOV  ES:[BX],AL     ;chistim zadvizhku
;---ustanovka registra maski karty dlya krasnogo cveta
   MOV  DX,3C4H        ;ukazyvaem na adresnyj registr
   MOV  AL,2           ;indeks registra maski karty
   OUT  DX,AL          ;ustanovka adresa
   INC  DX             ;ukazyvaem na registr dannyh
   MOV  AL,4           ;kod cveta
   OUT  DX,AL          ;posylaem kod cveta
;---risuem tochku
   MOV  AL,0FFH        ;lyuboe znachenie s ustanovlennym 7 bitom
   MOV  ES:[BX],AL     ;vyvodim tochku


Rezhim zapisi 1:

;---kopiruem stroku v sleduyushchuyu stroku
          MOV  CX,80       ;chislo bajtov v stroke
          MOV  BX,0        ;nachinaem s 1-go bajta bufera
          MOV  AX,0A000H   ;adres bufera
          MOV  ES,AX       ;
NEXT_BYTE:   MOV  AL,ES:[BX]   ;zapolnyaem zadvizhku
          MOV  ES:[BX]+80,AL   ;vyvodim v sleduyushchuyu stroku
          INC  BX          ;perehodim k sleduyushchemu bajtu
          LOOP NEXT_BYTE   ;

Rezhim zapisi 2:

;---risuem krasnuyu tochku v levom verhnem uglu ekrana
   MOV  AX,0A000H        ;adres bufera
   MOV  ES,AX            ;
   MOV  BX,0             ;ukazyvaem na pervyj bajt bufera
;---ustanovka registra maski bitov
   MOV  DX,3CEH          ;ukazyvaem na adresnyj registr
   MOV  AL,8             ;registr maski bitov
   OUT  DX,AL            ;adresuem registr
   INC  DX               ;ukazyvaem na registr dannyh
   MOV  AL,10000000B     ;maskiruem vse bity, krome 7-go
   OUT  DX,AL            ;posylaem dannye
;---risuem krasnuyu tochku
   MOV  AL,ES:[BX]       ;zapolnyaem registry zadvizhki
   MOV  AL,4             ;krasnyj cvet
   MOV  ES:[BX],AL       ;risuem tochku





   Dlya graficheskih rezhimov cvetnogo adaptora ili PCjr opredelenie
cveta tochki na nizkom urovne sostoit v obrashchenii procedury vyvoda
tochki:  programma  chitaet iz videobufera i vydelyaet  interesuyushchie
bity.  Odnako dlya EGA etot metod  neprigoden, poskol'ku v rezhimah
DH  - 10H kazhdomu adresu pamyati sootvetstvuet dva ili chetyre baj-
ta.  EGA imeet dva rezhima chteniya, chtoby preodolet' etu trudnost'.
Imejte  vvidu, chto dlya PCjr i EGA, posle togo, kak Vy  opredelili
kod cveta tochki, neobhodimo eshche  proverit' ustanovku tekushchego re-
gistra  paletty  dlya etogo koda, chtoby opredelit' kakoj cvet  emu
pripisan.
   Lyuboj yazyk programmirovaniya imeet dostup k dvum rezhimam chteniya
EGA.   V rezhime 0 vozvrashchaetsya bajt, soderzhashchijsya vo vseh chetyreh
bitovyh ploskostyah, po ukazannomu  adresu. Rezhim 1 ishchet ukazannyj
kod cveta i vozvrashchaet bajt, v kotorom bit ustanovlen v 1,  kogda
sootvetstvuyushchaya tochka imeet  dannyj  cvet.  Bit 3 registra rezhima
opredelyaet kakoj rezhim chteniya ustanovlen (0 = rezhim 0).  Dostup k
etomu registru osushchestvlyaetsya cherez port 3CFH i Vy dolzhny predva-
ritel'no poslat' 5 v port 3CEH, chtoby vybrat' etot registr. Obych-
no vse ostal'nye bity etogo  registra,  kotoryj  mozhno tol'ko pi-
sat',  sbrosheny v 0, krome bitov 0 i 1, kotorye opredelyayut  rezhim
zapisi. Poskol'ku pri inicializacii BIOS ustanavlivaet eti bity v
rezhim  zapisi  0 (tak chto oni oba ravny 0), to obychno  Vam  nuzhno
prosto poslat' v etot registr 0, chtoby  ustanovit' rezhim chteniya 0
i poslat' 8, chtoby ustanovit' rezhim chteniya 1.
   Rezhim  chteniya  0 trebuet, chtoby Vy  predvaritel'no  ustanovili
registr vybora karty.  Edinstvennaya zadacha etogo registra - usta-
novit', kakaya iz kart bitov dolzhna byt' prochitana. Poetomu v nego
nado poslat' chislo ot 0 do 3. |tot registr imeet adres porta 3CFH
i  nado predvaritel'no poslat' 4 v port 3CEH, chtoby ukazat'  etot
registr.
   Rezhim chteniya 1 bolee slozhen.  Snachala registr sravneniya cvetov
dolzhen  byt'  zapolnen cepochkoj bitov dlya koda cveta, kotoryj  Vy
ishchete.  |tot kod pomeshchaetsya v  mladshie 4 bita registra; starshie 4
bita - nesushchestvenny. |tot registr imeet adres porta 3CFHi ukazy-
vaetsya predvaritel'noj zasylkoj 2 v port 3CEH. Posle chteniya yachej-
ki pamyati vozvrashchaetsya bajt, kotoryj imeet bity ustanovlennye v 1
dlya kazhdoj tochki, imeyushchej nuzhnyj cvet. Odnako za schet ispol'zova-
niya  registra bezrazlichiya cveta (color don't care register)  odin
ili bolee bitov koda  cveta  mogut  pri sravnenii ignorirovat'sya.
Obychno  4 mladshih bita etogo registra ustanovleny v 1;  obnulenie
odnogo iz etih bitov privedet k  tomu,  chto soderzhimoe sootvetst-
vuyushchej  bitovoj  ploskosti budet ignorirovat'sya.  Naprimer,  esli
cepochka bitov dlya tochki 3 (bit 3) po ukazannomu adresu ravna 0110
i registr sravneniya cvetov soderzhit znachenie 0010, to pri sravne-
nii budet vozvrashchen bajt, u  kotorogo  bit  3 raven 0, esli v re-
gistre bezrazlichiya cvetov vse bity ravny 1.  No esli registr bez-
razlichiya cvetov soderzhit 1011, to v bajte, vozvrashchaemom processo-
ru bit 3 budet raven 1.
   Registr  bezrazlichiya cvetov imeet adres porta 3CFH i  indeksi-
ruetsya zasylkoj 7 v port 3CEH. Starshie 4 ego bita ne igrayut nika-
koj  roli.  Otmetim, chto dokumentaciya IBM (ot 2 avgusta 1984  g.)
utverzhdaet chto registr dejstvuet obratnym  obrazom, t.e., chto 1 v


registre zastavlyaet operaciyu sravneniya ignorirovat' sootvetstvuyu-
shchuyu bitovuyu ploskost'. |ksperiment pokazyvaet obratnoe.
   Ni odin iz etih dvuh  rezhimov  chteniya  ne  mozhet  dat' bystryj
otvet  na  vopros o cvete opredelennoj tochki.  V rezhime chteniya  0
neobhodimy 4 otdel'nyh chteniya, po odnomu dlya kazhdoj bitovoj plos-
kosti, posle chego nado eshche vydelit' sootvetstvuyushchie bity iz  kazh-
dogo bajta. V rezhime chteniya 1,  s  drugoj storony, mozhet potrebo-
vat'sya do 16 chtenij, prezhde chem dlya trebuemoj tochki budet vozvra-
shchen ustanovlennyj  bit,  ukazyvayushchij  chto  eta tochka imeet dannyj
cvet.  No hotya EGA otnositel'no medlenno vypolnyaet dannuyu zadachu,
zato dlya drugih celej on rabotaet ochen' bystro.

   Vysokij uroven'.

   Bejsik predostavlyaet funkciyu  POINT,  kotoraya  vozvrashchaet cvet
tochki. Cvet paletty tochki, nahodyashchejsya v stolbce 200 i stroke 100
nahoditsya putem Q = POINT(200,100).  Znachenie, vozvrashchaemoe v Q -
eto obychnyj kodovyj nomer cveta.  Esli ukazana tochka, nahodyashchayasya
za predelami ekrana,  to  funkciya  POINT  vozvrashchaet znachenie -1.
Kogda  koordinatnaya sistema ekrana izmenyaetsya  operatorom  WINDOW
[4.4.2], to funkciya POINT perehodit k novoj sisteme.
   POINT mozhet takzhe soobshchit' poziciyu poslednej vyvedennoj tochki.
Pri  ispol'zovanii  obychnoj koordinatnoj sistemy, v  kotoroj  0,0
sootvetstvuet levomu verhnemu  uglu  ekrana, Q = POINT(1) vozvra-
shchaet v Q x-koordinatu tochki, a Q = POINT(2) - y-koordinatu.  Esli
dejstvuet operator WINDOW, to Q = POINT(3) i Q = POINT(4) vozvra-
shchaet x- i y-koordinaty v novoj sisteme.  Kogda net aktivnogo ope-
ratora WINDOW, to poslednie dva operatora dejstvuyut tak zhe, kak i
pervye dva.
   K  momentu vyhoda etoj knigi Bejsik ne podderzhival  uluchshennye
graficheskie rezhimy EGA (D-10H).  V  etih rezhimah programma dolzhna
pryamo  chitat'  soderzhimoe videobufera.  Vot primer  ispol'zovaniya
rezhima chteniya 1 dlya poiska kodov cvetov 0001 i 1001:

100 OUT &H3CE,5         'adres registra rezhima
110 OUT &H3CF,8         'ustanavlivaem rezhim chteniya 0
120 OUT &H3CE,2         'adres registra sravneniya cvetov
130 OUT &H3CF,1         'ishchem cvet 0001
140 OUT &H3CE,7         'adres registra bezrazlichiya cvetov
150 OUT &H3CF,7         '7 = 0111B, poetomu m. b. 0001 i 1001
160 DEF SEG = &HA000    'adres videobufera dlya EGA
170 X = PEEK(0)         'chitaem pervyj bajt
180 IF X <> 0 THEN...   '..to cvet 0001 ili 1001 najden

   Srednij uroven'.

   Funkciya D preryvaniya 10H vozvrashchaet kod cveta ukazannoj tochki.
BIOS  imeyushchijsya na plate EGA obespechivaet, chto eta funkciya  rabo-
taet v lyubom rezhime displeya.  Nado pomestit' nomer stroki (otschi-
tyvaemyj ot 0) v DX, a nomer stolbca (takzhe otschityvaemyj ot 0) -
v CX. Rezul'tat vozvrashchaetsya v AL.


;---opredelyaem kod paletty tochki 100,200
   MOV  AH,0DH       ;nomer funkcii chteniya cveta tochki
   MOV  DX,100       ;nomer stroki
   MOV  CX,200       ;nomer stolbca
   INT  10H          ;teper' kod cveta v AL

   Nizkij uroven'.

   Dlya graficheskih rezhimov  cvetnogo  adaptora i PCjr nado prosto
obratit' process pryamogo otobrazheniya v pamyat', kotorym ustanavli-
vaetsya cvet tochki,  kak  pokazano  v  [4.4.2].  Mozhno ispo'zovat'
privedennyj tam primer, kotoryj nado zavershit' sleduyushchim kodom:

;---izmenenie bitov (mesto dlya vstavki izmenenij)
   MOV  AH,ES:[BX]     ;berem bajt iz nuzhnoj pozicii
   ROR  AH,CL          ;sdvigaem 2 nuzhnyh bita vniz
   AND  AH,00000011B   ;vyklyuchaem ostal'nye bity
   RET                 ;teper' v AH - kod paletty

   Dlya  rezhimov  EGA ot DH do 10H nado  pol'zovat'sya  registrami,
kotorye byli opisany vyshe.   V  sleduyushchem  primere rezhim chteniya 0
ispo'zuetsya dlya chteniya bitovoj ploskosti 2 po adresu A000:0012.

;---ustanovka rezhima chteniya
   MOV  DX,3CEH       ;indeksnyj registr
   MOV  AL,5          ;snachala adresuem registr rezhima
   OUT  DX,AL         ;posylaem indeks
   INC  DX            ;ukazyvaem na sam registr
   MOV  AL,0          ;ustanavlivaem rezhim chteniya 0
   OUT  DX,AL         ;
;---ustanovka bitovoj ploskosti, kotoruyu budem chitat'
   DEC  DX            ;nazad k indeksnomu registru
   MOV  AL,4          ;adres registra vybora karty
   OUT  DX,AL         ;posylaem indeks
   INC  DX            ;ukazyvaem na sam registr
   MOV  AL,2          ;zapros bitovoj ploskosti 2
   OUT  DX,AL         ;posylaem znachenie
;---chtenie bitovoj ploskosti
   MOV  AX,0A000H     ;adres videobufera
   MOV  ES,AX         ;
   MOV  BX,12         ;smeshchenie v bufere
   MOV  AL,ES:[BX]    ;chitaem iz bitovoj ploskosti 2

I,  nakonec, primer poiska kodov cveta 0010 i 1010 s  ispol'zova-
niem rezhima chteniya 1:

;---ustanovka rezhima chteniya
   MOV  DX,3CEH       ;registr indeksa
   MOV  AL,5          ;adresuem snachala registr rezhima
   OUT  DX,AL         ;posylaem indeks
   INC  DX            ;ukazyvaem na sam registr
   MOV  AL,8          ;ustanavlivaem bit 3 dlya rezhima 1
   OUT  DX,AL         ;ustanavlivaem rezhim


;---ustanovka registra sravneniya cvetov
   DEC  DX            ;vozvrashchaemsya k indeksnomu registru
   MOV  AL,2          ;adres registra sravneniya cvetov
   OUT  DX,AL         ;posylaem indeks
   INC  DX            ;ukazyvaem na sam registr
   MOV  AL,0010B      ;kod cveta
   OUT  DX,AL         ;posylaem kod
;---ustanovka registra bezrazlichiya cvetov
   DEC  DX            ;vozvrashchaemsya k indeksnomu registru
   MOV  AL,7          ;adres registra bezrazlichiya cvetov
   OUT  DX,AL         ;posylaem indeks
   INC  DX            ;ukazyvaem na sam registr
   MOV  AL,0111B      ;prinimaem kody 1010 ili 0010
   OUT  DX,AL         ;posylaem dannye
;---poisk cveta
   MOV  AX,0A000H     ;adres videobufera
   MOV  ES,AX         ;
   MOV  BX,12         ;smeshchenie v bufere
   MOV  AL,ES:[BX]    ;chitaem poziciyu bufera
   CMP  AL,0          ;ustanovleny bity?
   JNZ  FOUND_IT      ;esli da, to ishchem u kakoj tochki





   Prostejshij  sposob  narisovat' liniyu na ekrane sostoit v  tom,
chtoby vychislit' sleduyushchuyu tochku etoj  linii i izmenit' bity soot-
vetstvuyushchego bajta. Takie operacii ochen' medlenny, hotya inogda ih
nel'zya izbezhat'.  Esli eto  vozmozhno,  to luchshe vychislit' oblast'
tochek  ekrana,  kotorye imeyut odinakovyj cvet.   Togda  trebuemye
operacii nad bitami  mozhno  prodelat'  tol'ko nad odnim bajtom, a
zatem  etot  bajt  mozhet byt' pomeshchen v  oblast'  sootvetstvuyushchih
pozicij videobufera.

   Vysokij uroven'.

   Bejsik pozvolyaet  risovat'  pryamye  linii  s pomoshch'yu operatora
LINE. LINE (20,10)-(40,30) risuet liniyu ot stolbca 20 i stroki 10
k stolbcu 40 i stroke 30. I  stroki i stolbcy numeruyutsya ot nulya.
Vy  mozhete opustit' koordinaty pervoj tochki, v etom sluchae  liniya
budet nachinat'sya s poslednej  tochki,  kotoraya byla ranee vyvedena
graficheskim  operatorom.  Vtoraya para koordinat mozhet  zadavat'sya
takzhe otnositel'no pervoj, s pomoshch'yu konstrukcii LINE -STEP(xoff-
set,yoffset).
   Operator  LINE mozhet ukazyvat' takzhe cvet i stil' linii.   Kod
cveta sleduet srazu za spiskom koordinat;  LINE (50,50)-(60,60),2
vyvodit  liniyu  cvetom 2.  Kogda cvet ne ukazan, to po  umolchaniyu
beretsya cvet 3.  Vozmozhnost' vybora stilya linii predpolagaet uka-
zanie cheredovaniya ee tochek. Obrazec mozhet davat'sya kak v desyatich-
noj, tak  i   v   shestnadcatirichnoj   forme.   Naprimer,  obrazec
1010101010101010, kotoryj sootvetstvuet &HAAAA, daet liniyu, tochki
kotoroj imeyut po ocheredi dannyj cvet i fonovyj. Stil' linii opre-
delyaetsya  tret'im  parametrom posle  koordinat.   Naprimer,  LINE
(30,30)-(40,40),3,,&HAAAA vyvodit liniyu s ukazannym stilem cvetom
3.
   Bejsik predostavlyaet takzhe procedury dlya risovaniya pryamougol'-
nikov i okruzhnostej. Pryamougol'niki vyvodyatsya s pomoshch'yu operatora
LINE. V dannom sluchae koordinaty dolzhny opisyvat' levyj verhnij i
pravyj nizhnij ugol ramki. Nado prosto ukazat' B (box - t.e.  ram-
ka)   v  kachestve  vtorogo  parametra  za   koordinatami.    LINE
(50,50)-(100,100),1,B,&HAAAA  risuet kvadrat so storonoj 50 tochek
cvetom 1 paletty, ispol'zuya vysheopisannyj stil'.  Dlya vyvoda prya-
mougol'nika, zapolnennogo  opredelennym  cvetom nado ispol'zovat'
parametr BF (pri etom stil' linii ukazyvat' ne nado).
   Okruzhnosti risuyutsya operatorom CIRCLE.  Ih vyvod  osnovyvaetsya
na formule CIRCLE (x,y),r,cvet,nach-ugol,kon-ugol,aspekt.  Koordi-
naty  x,y  dayut adres centra okruzhnosti na ekrane, a  r -  radius
okruzhnosti v tochkah; vsya ostal'naya informaciya neobyazatel'na. Cvet
-  eto  kod cveta, kotoryj po umolchaniyu beretsya  ravnym 3.   Esli
neobhodimo  vyvesti  tol'ko  dugu  okruzhnosti,  to  mozhno ukazat'
nach-ugol i kon-ugol (kogda oni opushcheny, to vyvoditsya celaya okruzh-
nost'). Ugly izmeryayutsya kak  polozhitel'nye  ili otricatel'nye ve-
lichiny,  otschityvaemye ot napravleniya po gorizontali vpravo.  Oni
izmeryayutsya v radianah (v 360 gradusah  soderzhitsya 6.292 radian, a
odin  gradus = 0.0174532 radian).  Aspekt eto otnoshenie  gorizon-
tal'nyh i vertikal'nyh razmerov. Kruglaya okruzhnost' poluchaetsya na
displee,  kogda Vy ukazhete ego ravnym 5/6 dlya umerennogo razreshe-


niya i 5/12 dlya vysokogo  razresheniya.  Men'shie znacheniya privodyat k
ellipsam, vytyanutym po gorizontali, a bol'shie - po vertikali. Dlya
primera PI=3.14159:  CIRCLE(200,50),30,2,PI/2,PI,6  vyvodit dugu,
centr kotoroj nahoditsya v tochke 50,200, s radiusom 30 tochek  cve-
tom 2, prichem budet vyveden  tol'ko levyj verhnij kvadrant verti-
kal'no vytyanutogo ellipsa.
   Bolee slozhnye linii mogut vyvodit'sya s pomoshch'yu operatora DRAW,
kotoryj neobychajno gibok. Za operatorom DRAW sleduet stroka (zak-
lyuchennaya  v  skobki), v kotoroj  zakodirovana  posledovatel'nost'
orientacij i dlin segmentov, sostavlyayushchih  liniyu.  Naprimer, DRAW
"E12F12G12H12"  vyvodit  bubnu.  Nachal'naya tochka  ustanavlivaetsya
operatorom PSET (obsuzhdaemym v  [4.4.2]);  v protivnom sluchae, po
umolchaniyu beretsya centr ekrana.  Osnovnye kody sostoyat iz  bukvy,
za kotoroj sleduet dlina segmenta v tochkah. Kody sleduyushchie:

   Ux        vverh (na x tochek)
   Dx        vniz
   Rx        vpravo
   Lx        vlevo
   Ex        po diagonali vverh i vpravo
   Fx        po diagonali vniz i vpravo
   Gx        po diagonali vniz i vlevo
   Hx        po diagonali vverh i vlevo

Pri umerennom razreshenii 100  tochek po gorizontali i 100 tochek po
vertikali  dayut otrezki primerno odinakovoj dliny (na samom  dele
otnoshenie y k x ravno 5/6). Pri vysokom razreshenii gorizontal'naya
liniya budet priblizitel'no vdvoe men'she, chem vertikal'naya.  Iz-za
bol'shego rasstoyaniya mezhdu tochkami diagonal' pryamougol'nika soder-
zhit  rovno stol'ko zhe tochek, skol'ko i maksimal'naya storona  prya-
mougol'nika, hotya sam otrezok dlinnee.
     Dlya risovaniya diagonalej s uglami, otlichnymi ot 45 gradusov,
ispol'zuetsya kodovaya bukva M.  |tot  kod risuet sleduyushchij segment
linii  v absolyutnuyu ili otnositel'nuyu poziciyu ekrana.  CHtoby uka-
zat' absolyutnuyu  poziciyu  nado  ukazat'  koordinaty  x  i y. DRAW
"M50,60"  provedet liniyu v tochku, imeyushchuyu koordinaty stolbca 50 i
stroki 60.  Dlya ukazaniya otnositel'nyh koordinat dobav'te znaki +
ili  - pered chislami.  Esli tekushchee znachenie  koordinaty x  ravno
100, to +50 prodolzhit liniyu  do  stolbca  150, a -50 - do stolbca
50.    CHtoby   sdvinut'sya  iz  100,100 v  120,70  napishite   DRAW
"M+20,-30".
   Liniya ne obyazana byt'  nepreryvnoj.  Kogda pered kodom ukazana
bukva  B, to ukazatel' peremeshchaetsya kak ukazano, no segment linii
pri etom ne risuetsya. Naprimer, DRAW "L10BU5R10" risuet dve para-
llel'nye  gorizontal'nye linii.  CHtoby iz odnoj tochki  nachinalos'
neskol'ko segmentov  nado  ukazat'  pered  kodom bukvu N.  V etom
sluchae ukazatel' budet vozvrashchat'sya v nachal'nuyu tochku posle vyvo-
da segmenta.
   Imeetsya  ryad  special'nyh  kodov,  kotorye  buduchi pomeshchennymi
vnutri  stroki, dejstvuyut na vse posleduyushchie kody (poka sleduyushchij
analogichnyj kod ne ukazhet  drugoe  dejstvie). Cvet segmenta linii
ustanavlivaetsya  bukvoj  C, za kotoroj sleduet kod  cveta.   DRAW
"C2D5" risuet liniyu, napravlennuyu  vniz cvetom 2. Ustanovka massh-
tabnogo faktora menyaet masshtab, v kotorom budet vyvodit'sya figura


ili ee chast'.  Nado dobavit' k stroke bukvu S, za kotoroj sleduet
faktor.  Faktor eto chislo, kotoroe dlya polucheniya masshtaba delitsya
na 4.  Obychno faktor raven  4,  chto  sootvetstvuet  masshtabu 1:1.
Izmenenie  faktora  na 8 privedet k tomu,  chto  razmer  vyvodimoj
figury budet vdvoe bol'she. Dlya  etogo  napishite DRAW "S8U12D12" i
t.d.
   Ispol'zuya odin ih dvuh kodov Vy mozhete vrashchat' osi  koordinat-
noj sistemy. Kodovaya bukva A vrashchaet osi protiv chasovoj strelki s
90-gradusnymi inkrimentami. A0 ne vrashchet osi voobshche. A1 - povora-
chivaet ih na 90 gradusov,  A2  -  na  180  gradusov i A3 - na 270
gradusov.  Analogichno, kod TA povorachivaet osi na ukazannoe chislo
gradusov ot 0 do 360 (protiv chasovoj  strelki) i ot 0 do -360 (po
chasovoj strelke).  DRAW "A1L10" i DRAW "TA90L10" privedut k tomu,
chto liniya, kotoraya  dolzhna  byla  byt'  napravlennoj  vlevo budet
vmesto  etogo  narisovana povernutoj na 90 gradusov i  napravlena
vniz.
   Operator DRAW mozhet  vklyuchat'  strokovye  peremennye,  kotorye
sostoyat iz nabora dopustimyh kodov.  |to svojstvo pozvolyaet prog-
ramme povtorno ispol'zovat'  chasti  figur v razlichnyh risunkah. V
operatore  DRAW imya stroki dolzhno byt' pomeshcheno za bukvoj X i  za
nim dolzhny sledovat' tochka s zapyatoj. Naprimer:

100 S$ = "U12R15U45L32"
110 DRAW "XS$;"

V odnom operatore DRAW mozhet soderzhat'sya neskol'ko strok, pereme-
zhaemyh drugimi kodami.  Otmetim, chto lyubye chisla, ispol'zuemye  s
kodami v operatorah DRAW mogut sami byt' peremennymi. Takim obra-
zom  s  pomoshch'yu  odnogo operatora DRAW mogut  vyvodit'sya  figury,
otlichayushchiesya po forme, cvetu, masshtabu  i orientacii. Nado pomes-
tit' znak ravenstva mezhdu bukvennym kodom i imenem peremennoj,  a
za imenem pomestit' tochku s zapyatoj.   Naprimer, chtoby ustanovit'
kod  cveta, opredelyaemyj peremennoj, napishite  DRAW  "C=PCOLOR;".
Kompilyator Bejsika trebuet,  chtoby  ssylka na eti peremennye osu-
shchestvlyalas' s pomoshch'yu funkcii VARPTR$. V etom sluchae takoj opera-
tor budet imet' vid  DRAW  "X"  +  VARPTR$(S$)  ili  DRAW  "C=" +
VARPTR$(PCOLOR). Slozhnye risunki mogut byt' sohraneny v massive i
zatem vozvrashcheny na ekran v lyuboj moment. Obsuzhdenie etogo vopro-
sa sm. v [4.4.6].

   Nizkij uroven'.

   Nizheprivedennaya  procedura ispol'zuet algoritm Brezenhema  dlya
vyvoda pryamoj linii, soedinyayushchej lyubye dve tochki.  Ona ispol'zuet
funkciyu  BIOS ustanovki tochek i ee mozhno ubystrit' esli  zamenit'
etu funkciyu na vstroennuyu proceduru,  ispol'zuyushchuyu pryamoe otobra-
zhenie  v  pamyat'.  Kak i vse bystrye algoritmy  dannaya  procedura
izbegaet operacij umnozheniya i deleniya.  Liniya rassmatrivaetsya kak
nabor segmentov dvuh tipov: teh kotorye raspolozheny diagonal'no i
teh, kotorye raspolozheny gorizontal'no ili vertikal'no. Dlya linij
s  naklonom  bol'she 1 pryamye  segmenty  vertikal'ny, v  protivnom
sluchae oni gorizontal'ny;  pervaya  zadacha algoritma sostoit v vy-
chislenii naklona. Zatem vychislyaetsya vyravnivayushchij faktor, kotoryj
sledit chtoby nekotoroe chislo pryamyh  segmentov imelo bol'shuyu dli-


nu,  chem ostal'nye.  I, nakonec, slozhnyj cikl poocheredno  vyvodit
diagonal'nye i pryamye segmenty.  BX poocheredno prinimaet to polo-
zhitel'nye,  to otricatel'nye znacheniya, otmechaya kakoj tip segmenta
vyvoditsya.  Nizhe gotovyatsya  dannye dlya vyvoda diagonali iz odnogo
ugla ekrana v protivopolozhnyj:

;---v segmente dannyh
START_X                   DW   0
END_X                     DW   319
START_Y                   DW   0
END_Y                     DW   199
COLOR                     DB   2
DIAGONAL_Y_INCREMENT      DW   ?
DIAGONAL_X_INCREMENT      DW   ?
SHORT_DISTANCE            DW   ?
STRAIGHT_X_INCREMENT      DW   ?
STRAIGHT_Y_INCREMENT      DW   ?
STRAIGHT_COUNT            DW   ?
DIAGONAL_COUNT            DW   ?

;---ustanovka rezhima displeya
               MOV  AH,0       ;funkciya ustanovki rezhima
               MOV  AL,4       ;cvetnoj 320*200
               INT  10H        ;ustanovka rezhima
;---ustanovka nachal'nyh inkrementov dlya kazhdoj pozicii tochki
               MOV  CX,1       ;inkrement dlya osi x
               MOV  DX,1       ;inkrement dlya osi y
;---vychislenie vertikal'noj distancii
               MOV  DI,END_Y   ;vychitaem koordinatu nachal'noj
               SUB  DI,START_Y ;tochki iz koordinaty konechnoj
               JGE  KEEP_Y     ;vpered esli naklon < 0
               NEG  DX         ;inache inkrement raven -1
               NEG  DI         ;a distanciya dolzhna byt' > 0
KEEP_Y:        MOV  DIAGONAL_Y_INCREMENT,DX
;---vychislenie gorizontal'noj distancii
               MOV  SI,END_X   ;vychitaem koordinatu nachal'noj
               SUB  SI,START_X ;tochki iz koordinaty konechnoj
               JGE  KEEP_X     ;vpered esli naklon < 0
               NEG  CX         ;inache inkrement raven -1
               NEG  SI         ;a distanciya dolzhna byt' > 0
KEEP_X:        MOV  DIAGONAL_Y_INCREMENT,CX
;---opredelyaem gorizontal'ny ili vertikal'ny pryamye segmenty
               CMP  SI,DI      ;gorizontal'nye dlinnee?
               JGE  HORZ_SEG   ;esli da, to vpered
               MOV  CX,0       ;inache dlya pryamyh x ne menyaetsya
               XCHG SI,DI      ;pomeshchaem bol'shee v CX
               JMP  SAVE_VALUES;sohranyaem znacheniya
HORZ_SEG:      MOV  DX,0       ;teper' dlya pryamyh ne menyaetsya y
SAVE_VALUES:   MOV  SHORT_DISTANCE,DI  ;men'shee rasstoyanie
               MOV  STRAIGHT_X_INCREMENT,CX  ;odin iz nih 0,
               MOV  STRAIGHT_Y_INCREMENT,DX  ;a drugoj - 1.


;---vychislyaem vyravnivayushchij faktor
               MOV  AX,SHORT_DISTANCE  ;men'shee rasstoyanie v AX
               SHL  AX,1       ;udvaivaem ego
               MOV  STRAIGHT_COUNT,AX  ;zapominaem ego
               SUB  AX,SI      ;2*men'shee - bol'shee
               MOV  BX,AX      ;zapominaem kak schetchik cikla
               SUB  AX,SI      ;2*men'shee - 2*bol'shee
               MOV  DIAGONAL_COUNT,AX  ;zapominaem
;---podgotovka k vyvodu linii
               MOV  CX,START_X ;nachal'naya koordinata x
               MOV  CX,START_Y ;nachal'naya koordinata y
               INC  SI         ;pribavlyaem 1 dlya konca
               MOV  AL,COLOR   ;berem kod cveta
;---teper' vyvodim liniyu
MAINLOOP:      DEC  SI         ;schetchik dlya bol'shego rasstoyaniya
               JZ   LINE_FINISHED  ;vyhod posle poslednej tochki
               MOV  AH,12      ;funkciya vyvoda tochki
               INT  10H        ;vyvodim tochku
               CMP  BX,0       ;esli BX < 0, to pryamoj segment
               JGE  DIAGONAL_LINE  ;inache diagonal'nyj segment
;---vyvodim pryamye segmenty
               ADD  CX,STRAIGHT_X_INCREMENT  ;opredelyaem inkre-
               ADD  DX,STRAIGHT_Y_INCREMENT  ;menty po osyam
               ADD  BX,STRAIGHT_COUNT  ;faktor vyravnivaniya
               JMP  SHORT MAINLOOP  ;na sleduyushchuyu tochku
;---vyvodim diagonal'nye segmenty
DIAGONAL_LINE: ADD  CX,DIAGONAL_X_INCREMENT  ;opredelyaem inkre-
               ADD  DX,DIAGONAL_Y_INCREMENT  ;menty po osyam
               ADD  BX,DIAGONAL_COUNT  ;faktor vyravnivaniya
               JMP  SHORT MAINLOOP  ;na sleduyushchuyu tochku
LINE_FINISHED:





   Tshchatel'noe  obdumyvanie  pozvolyaet  isklyuchit'  mnogo  izlishnej
medlitel'nosti, kotoraya svojstvenna  mnogim programmam zapolneniya
oblastej  dlya graficheskogo ekrana.  Kogda zapolnenie osnovano  na
prostyh  vychisleniyah,  kotorye  dejstvuyut  po  ocheredi dlya kazhdoj
tochki,  to trebuyutsya rashoduyushchie mnogo vremeni bitovye  operacii.
Bolee ekonomnyj kod mozhet opredelyat' vse li bitovye pozicii opre-
delennogo  bajta  videobufera dolzhny imet' odin i tot zhe  cvet  i
kogda eto uslovie vypolnyaetsya, to etomu bajtu prisvaivaetsya zara-
nee  zagotovlennoe  znachenie, kotoroe ustanavlivaet vse  tochki  v
pravil'nyj cvet. Pri etom  net  neobhodimosti  povtoryat' operacii
nad  odnim  i tem zhe bajtom, kazhdyj raz ustanavlivaya bity  tol'ko
dlya odnoj iz tochek, informaciyu o kotoroj soderzhit dannyj bajt.
   V [4.3.4] ob®yasneno kak sozdat' opisanie simvola v vide matri-
cy  8*8  tochek, imeyushchego trebuemyj Vam vid.  Hotya  takie  simvoly
mogut vyvodit'sya tol'ko v  standartnye  simvol'nye pozicii, no ih
ispol'zovanie  mozhet sushchestvenno oblegchit'  zapolnenie  grafikov.
Obrazec vysvechivayushchij vse 8*8 tochek mozhet byt' vyveden v interva-
le neskol'kih strok i stolbcov, zapolnyaya oblast' namnogo bystree,
chem eto dostigaetsya pri potochechnoj zarisovke.  |tot tip grafiches-
kih simvolov mozhet ispol'zovat'sya sovmestno s tochechnoj  grafikoj.
Psevdograficheskie simvoly mogut  ispol'zovat'sya  takzhe dlya vyvoda
vrashchayushchihsya ili koleblyushchihsya ob®ektov.

   Vysokij uroven'.

   Bejsik  predostavlyaet operator PAINT dlya zapolneniya  zamknutoj
figury proizvol'noj formy.  Vam  neobhodimo  ukazat' tol'ko tochku
vnutri oblasti, a ob ostal'nom pozabotitsya procedura.  Mozhet byt'
ukazan cvet paletty, kotorym  nado  zapolnit'  oblast', naprimer,
PAINT  (100,110),2 zapolnyaet oblast' cvetom 2 paletty.   Zakraska
vedetsya nachinaya ot ukazannoj tochki do teh por, poka ne vstretyatsya
tochki  s cvetom, otlichayushchimsya ot fonovogo.  Vy mozhete,  naoborot,
ukazat' cvet granicy i zakraska  budet  prodolzhat'sya vo vseh nap-
ravleniyah,  poka ne budut vstrecheny tochki ukazannogo cveta.   Pri
takoj zakraske linii drugih  cvetov,  nahodyashchiesya vnutri granicy,
mogut  byt' takzhe zakrasheny.  Kod cveta granicy sleduet za  kodom
cveta zapolneniya, takim obrazom  PAINT  (100,180),2,3 zakrashivaet
oblast' cvetom 2 do linij cveta 3.  Otmetim, odnako, chto eta pro-
cedura ne zapolnyaet oblasti,  nahodyashchiesya  "za  uglom", t.e. esli
vdol'   kakoj-libo  gorizontal'noj  ili  vertikal'noj  traektorii
vstretilas' tochka, imeyushchaya cvet granicy, to vse posleduyushchie tochki
vdol'  etoj  traektorii ne zapolnyayutsya, dazhe  esli  figura  imeet
prichudlivuyu formu i eti tochki  prinadlezhat vnutrennej chasti figu-
ry.  V sleduyushchem primere vyvodyatsya dve perekryvayushchihsya ramki cve-
tami cian i magenta, a zatem  poslednyaya  ramka  zapolnyaetsya belym
cvetom.   Segmenty  pervoj ramki, kotorye popadayut v  zakrashennuyu
oblast' takzhe zapolnyayutsya belym.

100 LINE (50,70)-(270,130),1,B   'risuem ramku cvetom cian
110 LINE (100,30)-(220,170),2,B  'risuem ramku cvetom magenta
120 PAINT (101,31),3,2           'zapolnyaem vtoruyu ramku belym


Pomnite, chto komanda  LINE  mozhet  sama  zapolnit' ramku, esli Vy
ukazhete v kachestve parametra 'BF', a ne 'B'. Smotrite [4.4.5].
   Operator  PAINT  imeet "ornamental'nye"  vozmozhnosti,  kotorye
pozvolyayut Vam zapolnyat'  oblasti  ukazannoj  kartinkoj.  |lementy
ornamenta, kotorye v rezhime umerennogo razresheniya imeyut razmer  4
tochki v shirinu i 8 v vysotu (8*8  dlya vysokogo razresheniya) povto-
ryayutsya  po vsej ukazannoj oblasti.  Risunok  opisyvaetsya  naborom
bajtov, soderzhashchih cepochku bitov  dlya posledovatel'nyh ryadov ele-
menta  ornamenta.  V rezhime umerennogo razresheniya  cepochka  bitov
10000011 opisyvaet 4 tochki,  pervaya iz kotoryh imeet cvet 2, sle-
duyushchie 2 - fonovyj cvet, a poslednyaya - cvet 3.  |ta cepochka soot-
vetstvuet chislu 131 ili &H83 (sm.  prilozhenie B, v kotorom obsuzh-
dayutsya  bitovye  operacii v Bejsike).  Obrashchenie etoj  cepochki  v
11000010 dast 193 (&HC1).  Oni  mogut  byt'  ob®edineny v element
ornamenta  shirinoj v 4 tochki i vysotoj v 2 strokoj  CHR$(&H83)  +
CHR$(&HC1). V takuyu stroku  mogut  vklyuchat'sya do 8 bajtov, dovodya
vysotu  do 8 tochek.  Takaya stroka ispol'zuetsya v operatore  PAINT
vmesto cveta. Vot vyvod kvadrata, zapolnennogo opisannym ornamen-
tom:

100 LINE (100,110)-(150,150),1,B     'risuem ramku
110 PAINT (125,125),CHR$(&H83)+CHR$(&HC1),1   'zapolnyaem ee

Otmetim,  chto neregulyarnosti elementa ornamenta mogut privodit' k
tomu, chto procedura  PAINT  zavershaetsya,  ne  zakonchiv zapolneniya
oblasti.  Bejsik reshaet etu problemu ukazaniem parametra fona dlya
operatora PAINT.  Esli u  Vas  vozniknut  problemy, obrashchajtes' k
rukovodstvu po Bejsiku za detalyami.
   Operator DRAW, pozvolyayushchij risovat' slozhnye linii, takzhe mozhet
zapolnyat' oblasti. On obsuzhdaetsya v [4.4.5].  "Tekushchaya tochka" (iz
kotoroj  budet  risovat'sya sleduyushchij segment linii)  dolzhna  byt'
pomeshchena vnutr' oblasti, ogranichennoj  granicej ukazannogo cveta.
V stroku operatora DRAW nado pomestit' kodovuyu bukvu P, za  koto-
roj dolzhen sledovat' kod cveta zakraski i kod cveta granicy.  Dlya
vyvoda  ramki  cvetom 1 paletty, a zatem ee zapolneniya  cvetom  3
napishite  DRAW  "U10R10D10L10BH1P3,1".  Zdes'  pervye chetyre koda
risuyut  granicy  ramki, zatem kod 'BH' peremeshchaet  tekushchuyu  tochku
vnutr' ramki, ne risuya linii, a zatem kod 'P' privodit k zapolne-
niyu  ramki.  Takim obrazom mogut byt' zapolneny i  bolee  slozhnye
formy. Otmetim,  chto  neobyazatel'no  pri peremeshchenii tochki vnutr'
oblasti otmenyat' risovanie linii vdol' etogo puti. Odnako, v etom
sluchae nado ispol'zovat' dlya  etogo  segmenta kod cveta, otlichnyj
ot cveta zapolnyaemoj granicy.
   Bejsik  imeet  takzhe vozmozhnost'  zapolneniya  oblastej  ekrana
zaranee podgotovlennym izobrazheniem. Izobrazhenie mozhet byt' lyubo-
go razmera, mozhet byt' vyvedeno v lyuboj pozicii ekrana i hranitsya
v massive. Obychno, izobrazhenie sozdaetsya s pomoshch'yu vseh dostupnyh
sredstv,  a zatem zapominaetsya v massive operatorom GET.   Massiv
mozhet byt' pomeshchen v  posledovatel'nyj  fajl [5.4.3], iz kotorogo
programma mozhet zagruzit' ego i vyvesti izobrazhenie. Operator GET
perechislyaet koordinaty  levogo  verhnego  i  pravogo nizhnego ugla
ramki, soderzhashchej izobrazhenie, prichem snachala idet nomer stolbca,
a zatem nomer stroki  dlya  kazhdoj  pary  koordinat.  Zatem dolzhno
sledovat'  imya massiva, kotoroe ne zaklyuchaetsya v kavychki.  Napri-
mer, GET (80,40)-(120,60),ARRAY3 pomeshchaet  vse tochki, nahodyashchiesya


vnutri ukazannoj oblasti v massiv s imenem ARRAY3.
Odnomernye  massivy, kak i vse ostal'nye, dolzhny  byt'  predvari-
tel'no  opisany operatorom DIM.  Massiv mozhet soderzhat'  elementy
lyuboj tochnosti.  Dlya vychisleniya  trebuemyh  razmerov massiva nado
snachala opredelit' skol'ko bajtov potrebuetsya dlya hraneniya  izob-
razheniya. |to mozhno vychislit' po  formule 4 + INT ((x*bitovnatochku
+ 7)/8)* y.  Zdes' "bitovnatochku" ravno 1 dlya vysokogo razresheniya
i 2 - dlya umerennogo  razresheniya.  Bukvy  x i y otnosyatsya k chislu
tochek vdol' gorizontal'noj i vertikal'noj storon bloka  izobrazhe-
niya.  INT oboznachaet celuyu chast' chisla.  Nakonec, nado opredelit'
skol'ko  elementov  massiva trebuetsya dlya hraneniya dannogo  chisla
bajtov.  Kazhdyj element zanimaet  2 bajta v celom massive, no 4 -
dlya  chisel  s obychnoj tochnost'yu i 8 - dlya chisel s dvojnoj  tochno-
st'yu.
   Dlya polucheniya izobrazheniya  iz  massiva  i  vyvoda ego na ekran
ispol'zujte operator PUT. |tot operator trebuet tol'ko koordinaty
levogo verhnego ugla oblasti  ekrana,  v kotoruyu budet vyvodit'sya
izobrazhenie.   Za  koordinatami dolzhno byt' ukazano imya  massiva.
Naprimer, PUT (40,30),ARRAY1 pomeshchaet  izobrazhenie, levyj verhnij
ugol kotorogo budet nahodit'sya v stolbce 40 i stroke 30. Operator
PUT mozhet imet' eshche i neobyazatel'nyj parametr, opredelyayushchij cvet,
kotorym budet vyvodit'sya izobrazhenie.  Esli etot parametr opushchen,
to izobrazhenie budet vyvodit'sya  tochno  v tom vide, v kotorom ono
bylo  zapisano  operatorom  GET.   |to  ekvivalentno  zapisi  PUT
(40,30),ARRAY1,PSET.  V protivnom sluchae imeyutsya nekotorye drugie
vozmozhnosti. Esli Vy vmesto PSET ukazhete PRESET, to cvet 0 palet-
ty budet zamenen na cvet 3 i naoborot, a cvet 1 paletty - na cvet
2 i naoborot.
   Imeyutsya  eshche tri sluchaya, ispol'zuyushchie logicheskie operacii AND,
OR ili XOR.  Kak i PRESET eti  slova mogut zamenyat' PSET v prive-
dennom primere. Obsuzhdenie etih treh operacij smotrite v prilozhe-
nii B.  Kazhdaya  operaciya  vklyuchaet  sravnenie  bitov sushchestvuyushchej
tochki  na  ekrane s bitami tochki nakladyvaemogo  izobrazheniya.   V
rezhime vysokogo razresheniya, kogda na tochku otvoditsya tol'ko 1 bit
operaciya prostaya. No v rezhime umerennogo razresheniya, v kotorom na
kazhduyu tochku otvoditsya 2 bita, mogut proishodit' razlichnye trans-
formacii cvetov.
   AND ustanavlivaet bit tol'ko esli on byl ustanovlen i u  tochki
ekrana i u tochki izobrazheniya (vzyatoj iz massiva).  V rezhime vyso-
kogo  razresheniya eto oznachaet, chto tochka izobrazheniya poyavitsya  na
ekrane tol'ko esli  sootvetstvuyushchaya  tochka ekrana uzhe "vklyuchena".
Vse ostal'nye tochki oblasti budut vyklyucheny.  V rezhime umerennogo
razresheniya  operaciya  proizvoditsya  nad  oboimi  bitami. Esli dlya
tochki  ekrana  ustanovka bitov 01, a  dlya  sootvetstvuyushchej  tochki
izobrazheniya - 10, to oba bita budut sbrosheny i tochka ekrana polu-
chit kod 00, chto sootvetstvuet fonovomu cvetu.
   OR  ustanavlivaet  bit, esli on byl ustanovlen libo dlya  tochki
ekrana, libo dlya tochki izobrazheniya.  V cherno-belom rezhime OR nak-
ladyvaet  izobrazhenie  na sushchestvuyushchee izobrazhenie na ekrane.   V
cvetnom rezhime dlya opredeleniya effekta Vy opyat' dolzhny pribegnut'
k vychisleniyam. Kombinaciya kodov paletty 1(01) i 2(10) daet 3(11),
takzhe kak i kombinaciya 0(00) i 3(11).


   I, nakonec, XOR ustanavlivaet  bit,  esli iz dvuh sravnivaemyh
tol'ko  odin byl ustanovlen.  Primenenie etoj operacii  dlya  cher-
no-belogo ekrana s massivom edinic daet negativnoe izobrazhenie (1
i 1 daet 0, a 1 i 0 - daet 1). V rezhime umerennogo razresheniya eta
operaciya menyaet vse cveta. V  rezul'tate  poluchaem nalozhenie dvuh
izobrazhenij.   No  bolee vazhno, chto pri povtorenii etoj  operacii
ekran prinimaet v tochnosti takoj zhe vid, kotoryj on imel pervona-
chal'no.  Pri etom izobrazhenie stiraetsya.  |ta tehnika polezna dlya
mul'tiplikacii, kogda nad izobrazheniem dvazhdy proizvoditsya opera-
ciya XOR v odnoj pozicii, zatem v sosednej i t.d.

   Nizkij uroven'.

   Imeetsya mnogo podhodov k napisaniyu procedur zapolneniya  grafi-
cheskih ob®ektov. Ni odin iz nih  ne yavlyaetsya ideal'nym, poskol'ku
vsegda  imeetsya konflikt mezhdu skorost'yu raboty procedury i slozh-
nost'yu figur, kotorye ona mozhet  obrabatyvat'.  Lyubaya  procedura,
kotoraya zapolnyaet oblast' tochku za tochkoj budet medlennoj,  neza-
visimo ot togo, naskol'ko elegantno ona realizovana.  Imejte vvi-
du,  chto pochti kazhdaya modificiruemaya tochka  raspolozhena v  bajte,
vse tochki kotorogo budut izmenyat'sya v tot zhe samyj cvet.  Poluche-
nie  dostupa  k odnomu i tomu zhe bajtu s  ispol'zovaniem  slozhnyh
procedur trebuet sushchestvenno bol'she vremeni, chem ustanovka celogo
bajta  za odin dostup k yachejke videobufera.  Naprimer, potochechnaya
ochistka ekrana trebuet na IBM PC neskol'kih  sekund pri ispol'zo-
vanii funkcii BIOS, v to vremya kak pryamoj dostup v pamyat'  proiz-
vodit etu operaciyu mgnovenno:

      MOV  AX,0B800H     ;ES ukazyvaet na bufer ekrana
      MOV  ES,AX         ;
      MOV  CX,8192       ;zapolnyaem vse bajty
      MOV  AX,0          ;v kazhdyj bajt pishem 0
      MOV  DI,0          ;DI poocheredno ukazyvaet na vse bajty
REP   STOSW              ;povtoryaem zapis' 8192 raza

   Mnogie procedury zapolnyayut  po  odnoj  gorizontal'noj  stroke,
proveryaya na cvet granicy sprava i sleva. Poskol'ku stroki sostoyat
iz smezhnyh bajtov dannyh, to  nado  poocheredno brat' bajty iz vi-
deobufera  i proveryat' prisutstvuet li v nih cvet granicy.   Esli
cvet granicy otsutstvuet, to  mozhno  zamenit'  srazu ves' bajt na
cvet  zapolneniya.  V protivnom sluchae k dannomu bajtu primenyaetsya
potochechnyj podhod.
   Imeetsya ochen' bystryj sposob opredeleniya  prisutstvuet li gra-
nichnyj cvet v dannom bajte videobufera. Predpolozhim, chto procedu-
ra ishchet cvet 1 paletty v rezhime umerennogo  razresheniya s chetyr'mya
cvetami. |tomu cvetu sootvetstvuet kod 01, poetomu snachala zapol-
nim ves' bajt etim kodom: 01010101. Zatem ispol'zuem operaciyu NOT
dlya obrashcheniya kazhdogo bita, posle chego bajt primet vid  10101010.
Prodelaem operaciyu  XOR  so  znacheniem  vzyatym  iz videobufera; v
rezul'tate poluchim bajt, u kotorogo oba bita, otnosyashchiesya k odnoj
tochke ravny 1 tol'ko dlya  tochek,  imeyushchih  granichnyj cvet.  Zatem
snova ispol'zuem operaciyu NOT s tem, chtoby para bitov, otnosyashchih-
sya k tochke granichnogo cveta imela  kod 00. Posle etogo ispol'zuem
operaciyu  TEST dlya nahozhdeniya polej so znacheniem 00.  Esli  takoe


pole najdeno, to granichnyj cvet obnaruzhen i procedura perehodit k
obychnomu potochechnomu analizu dannogo bajta.  |tu proceduru  mozhno
eshche ubystrit', esli ispol'zovat' slovnye dannye.

   MOV  AL,ES:[BX]    ;berem bajt iz videobufera
   XOR  AL,10101010B  ;ustanavlivaem bity dlya cveta granicy
   NOT  AL            ;obrashchaem bity
   TEST AL,11000000B  ;proveryaem bity 7-6
   JZ   FOUND_BOUND   ;perehod esli granichnyj cvet
   TEST AL,00110000B  ;proveryaem bity 5-4
   JZ   FOUND_BOUND   ;perehod esli granichnyj cvet
   TEST AL,00001100B  ;proveryaem bity 3-2
   JZ   FOUND_BOUND   ;perehod esli granichnyj cvet
   TEST AL,00000011B  ;proveryaem bity 1-0
   JZ   FOUND_BOUND   ;perehod esli granichnyj cvet
   MOV  AL,FILL_COLOR ;granichnogo cveta net, zapolnyaem bajt
   MOV  ES:[BX],AL    ;vozvrashchaem bajt v videobufer
    .
    .
FOUND_BOUND:

   Kogda eto vozmozhno,  postarajtes', chtoby granicy pryamougol'nyh
oblastej  Vashih kartinok byli vyravneny na granicu dvuh,  chetyreh
ili vos'mi tochek, s tem chtoby  pryamoe  otobrazhenie v pamyat' imelo
delo s celymi bajtami.  Drugaya vozmozhnost', hotya i ne stol' byst-
raya, sostoit v sozdanii  opredelyaemyh  pol'zovatelem psevdografi-
cheskih  simvolov [4.3.4] i vyvode ih na granice oblasti  zapolne-
niya.  Koroche, v dannoj oblasti Vy imeete vse vozmozhnosti proyavit'
soobrazitel'nost',  a  zachastuyu  stoit podumat', a nuzhna  li  Vam
stol' slozhnaya grafika v dannoj zadache.





   Kogda Vy vyvodite izobrazhenie tochka za tochkoj, to eto otnimaet
ochen' mnogo vremeni, osobenno kogda  sozdayutsya effekty mul'tipli-
kacii.  Odin iz sposobov ekonomii vremeni sostoit v svedenii vseh
ili chasti vyvodimyh form k  figuram, kotorye mogut byt' postroeny
na matrice tochek 8*8.  Takie figury mogut byt' sozdany, kak opre-
delyaemye  pol'zovatelem  simvoly,  kak  pokazano v [4.3.4]. Posle
togo,  kak  eti simvoly opredeleny oni vyvodyatsya na  ekran  ochen'
bystro i prosto. |ti simvoly  mogut vyvodit'sya vperemeshku s poto-
chechnymi grafikami, kak obychnye bukvy.  Odin iz sposobov  bystrogo
zapolneniya figury sostoit v posledovatel'nom vyvode vnutri figury
polnost'yu  zakrashennogo bloka.  Otmetim, chto eti  simvoly  vsegda
raspolagayutsya v standartnyh poziciyah kursora.

   Srednij uroven'.

   V etom primere risuetsya figura  cheloveka, zanimayushchaya 2 simvola
v  vysotu i 2 simvola v shirinu.  Kak ob®yasneno v  [4.3.4]  vektor
preryvaniya 1FH ukazyvaet na  nachalo  oblasti dannyh, opredelyayushchih
simvoly.  CHetyre simvola mogut byt' vyvedeny obychnymi procedurami
DOS ili BIOS. Legko  sozdat'  drugoj  nabor  simvolov, dlya vyvoda
figury s rukami i nogami v drugom meste ekrana. Dva nabora simvo-
lov mogut poocheredno menyat'sya v sosednih poziciyah kursora, sozda-
vaya illyuziyu cheloveka, idushchego po ekranu.

;---v segmente dannyh
CHARACTER_DATA  DB   00110000B   ;levyj verhnij kvadrant
                DB   01100111B
                DB   01100111B
                DB   00110011B
                DB   00011111B
                DB   00001111B
                DB   00001111B
                DB   00000111B

                DB   00000011B   ;pravyj verhnij kvadrant
                DB   10001100B
                DB   10011000B
                DB   00110000B
                DB   11100000B
                DB   11000000B
                DB   11000000B
                DB   10000000B

                DB   00001111B   ;levyj nizhnij kvadrant
                DB   00011111B
                DB   00011100B
                DB   00011000B
                DB   00011000B
                DB   00110000B
                DB   01100000B
                DB   00010000B


                DB   11000000B   ;pravyj nizhnij kvadrant
                DB   11000000B
                DB   11000000B
                DB   11000000B
                DB   01100000B
                DB   01100000B
                DB   00010000B
                DB   00011110B
                DB   00000000B

;---ustanovka vektora preryvaniya
   PUSH DS                ;sohranyaem DS
   MOV  DX,OFFSET CHAR_DATA  ;smeshchenie dlya dannyh v DX
   MOV  AX,SEG CHAR_DATA  ;segment dlya dannyh v DS
   MOV  DS,AX             ;
   MOV  AH,25H            ;funkciya ustanovki vektora
   MOV  AL,1FH            ;nomer vektora
   INT  21H               ;ustanavlivaem vektor
   POP  DS                ;vosstanavlivaem DS

;---risuem figuru
;---pozicioniruem kursor na verhnij ryad
   MOV  AH,2         ;funkciya ustanovki kursora
   MOV  DH,13        ;stroka 13
   MOV  DL,20        ;stolbec 20
   MOV  BH,0         ;stranica 0
   INT  10H          ;ustanovka kursora
;---risuem verhnie dva simvola
   MOV  DL,128       ;berem simvol 128
   MOV  AH,2         ;funkciya vyvoda/kursor vpered
   INT  21H          ;vyvod simvola
   MOV  DL,129       ;berem simvol 129
   INT  21H          ;vyvodim ego
;---pozicioniruem kursor na nizhnyuyu stroku
   MOV  DH,14        ;stroka 14
   MOV  DL,20        ;stolbec 20
   MOV  AH,2         ;funkciya ustanovki kursora
   INT  10H          ;ustanavlivaem kursor
;---risuem nizhnie dva simvola
   MOV  DL,130       ;berem simvol 130
   MOV  AH,2         ;funkciya vyvoda/kursor vpered
   INT  21H          ;vyvod simvola
   MOV  DL,131       ;berem simvol 131
   INT  21H          ;vyvodim ego




   Sdvig ekrana i razbienie na stranicy - eto dva sposoba pereno-
sa bloka informacii iz pamyati na ekran. Pri sdvige odna iz granic
ekrana  sdvigaetsya  vnutr', stiraya informaciyu na  protivopolozhnoj
storone.  Zatem  osvobodivshayasya  oblast'  zapolnyaetsya  iz pamyati.
Povtorenie etogo dejstviya stroka za strokoj sozdaet illyuziyu sdvi-
ga ekrana.
   S drugoj storony, razbienie na  stranicy  osnovano na odnovre-
mennom  hranenii  neskol'kih ekranov informacii v  videobufere  i
pereklyuchenii vyvoda s odnoj  stranicy  na  druguyu.  Ispol'zovanie
displejnyh stranic nevozmozhno na monohromnom adaptore,  poskol'ku
ego pamyati hvataet tol'ko dlya odnogo  simvol'nogo ekrana.  Drugie
videosistemy  v  bol'shinstve ekrannyh rezhimov  mogut  rabotat'  s
neskol'kimi  stranicami.  Ispol'zovanie  stranic displeya osobenno
polezno  pri postroenii slozhnyh kartin "za kulisami"; posle  togo
kak eta  rabota  zavershena,  novyj  ekran  vyvoditsya momental'no.
Procedura,  imitiruyushchaya  rabotu  so stranicami  dlya  monohromnogo
adaptora privedena v  [4.5.3].   Ona  osobenno  polezna, kogda Vy
imeete delo s medlennym vyvodom na ekran v Bejsike.





   Kogda  tekstovyj ekran sdvigaetsya vverh, to stroki so  2-j  po
25-yu perepisyvayutsya na stroki s  1-j  po 24-yu, a sleduyushchaya stroka
dannyh  vyvoditsya v 25-j stroke.  Pri etom verhnyaya stroka, poverh
kotoroj osushchestvletsya  vyvod  teryaetsya,  hotya  ona prodolzhaet su-
shchestvovat' v pamyati. Sdvig vniz ustroen analogichno.

   Vysokij uroven'.

   Bejsik  utomitel'no medlitelen pri svoih manipulyaciyah s  ekra-
nom. Dlya bystrogo sdviga Vy mozhete pozhelat' ispol'zovat' procedu-
ru na mashinnom yazyke, kotoraya ne delaet nichego drugogo, krome kak
ispol'zuet preryvanie  10H,  kak  opisano  nizhe  v punkte srednij
uroven'. Procedura pozvolyaet sdvigat' ves' ekran ili lyuboe okno v
nem. Prilozhenie G pokazyvaet kak  vklyuchat' podprogrammy na mashin-
nom  yazyke  v Vashi programmy.  Vasha programma na  Bejsike  dolzhna
ukazyvat' koordinaty  verhnego  levogo  i  nizhnego  pravogo uglov
okna,  kotorye mogut lezhat' v diapazone ot 0 do 24 i ot 0 do  79.
Trebuetsya takzhe parametr,  ukazyvayushchij  napravlenie sdviga: vverh
ili  vniz  (6 i 7, sootvetstvenno), chislo strok na kotoroe  nuzhno
sdvinut' (esli 0, to okno  ochishchaetsya)  i znachenie bajta atributov
dlya ochishchaemyh strok (dlya "normal'nyh" - 7).  Ispol'zujte dlya  nih
celye peremennye. V  nizheprivedenno primere ekran sdvigaetsya vniz
na odnu stroku, a zatem osvobodivshayasya stroka osvobozhdaetsya.

100 '''dannye dlya podprogrammy
110 DATA &H55, &H8B, &HEC, &H8B, &H76, &H12, &H8A
120 DATA &H24, &H8B, &H76, &H10, &H8A, &H04, &H8B
130 DATA &H76, &H0E, &H8A, &H2C, &H8B, &H76, &H0C
140 DATA &H8A, &H0C, &H8B, &H76, &H0A, &H8A, &H34
150 DATA &H8B, &H76, &H08, &H8A, &H14, &H8B, &H76
160 DATA &H06, &H8A, &H3C, &HCD, &H10, &H5D, &HCA
170 DATA &H0E, &H00
180 '''pomeshchaem dannye v segment &H2000
190 DEF SEG = &H2000      'pomeshchaem dannye nachinaya s &H2000
200 FOR N = 0 TO 43       '44 bajta
210 READ Q                'chitaem odin bajt
220 POKE N,Q              'pomeshchaem ego v pamyat'
230 NEXT                  'sleduyushchij

300 '''v programme
310 GOSUB 500             'sdvigaem na stroku
320 LOCATE 1,1: PRINT TEXT$(LINEPTR);  'vyvodim stroku teksta

500 '''podprogramma sdviga
510 DEFINT A-Z            'ispol'zuem celye peremennye
520 TLR = 0               'levaya verhnyaya stroka
530 TLC = 0               'levyj verhnij stolbec
540 BRR = 24              'nizhnyaya pravaya stroka
550 BRC = 79              'nizhnij pravyj stolbec
560 NUMROWS = 1           'chislo strok sdviga
570 DIR = 7               'napravlenie sdviga vniz
580 FILL = 7              'zapolnenie obychnym atributom
590 DEF SEG = &H2000      'ukazyvaem na podprogrammu
600 SCROLL = 0            'nachinaem s 1-go bajta
610 CALL SCROLL(DIR,NUMROWS,TLR,TLC,BRR,BRC,FILL)
620 RETURN                'vse sdelano


   Srednij uroven'.

   Funkciya  6 preryvaniya 10H sdvigaet lyubuyu chast' ekrana vverh, a
funkciya 7 - vniz. V oboih sluchayah AL soderzhit chislo strok sdviga,
a  kogda AL = 0, to ves' ekran chistitsya, a ne sdvigaetsya.   CH:CL
soderzhat stroku i stolbec levogo  verhnego ugla, a DH:DL - soder-
zhat  koordinaty pravogo nizhnego ugla.  Poyavlyashchiesya  iz-za  sdviga
stroki chistye i oni vyvodyatsya s kodom atributov iz BH.

;---sdvig vverh na odnu stroku
   MOV  AH,6      ;nomer funkcii sdviga vverh
   MOV  AL,1      ;chislo strok sdviga
   MOV  CH,0      ;stroka levogo verhnego ugla
   MOV  CL,0      ;stolbec levogo verhnego ugla
   MOV  DH,24     ;stroka pravogo nizhnego ugla
   MOV  DL,79     ;stolbec pravogo nizhnego ugla
   MOV  BH,7      ;atributy ochishchaemoj stroki
   INT  10H       ;delaem sdvig

   Nizkij uroven'.

   Vertikal'nyj sdvig vsego  ekrana  eto trivial'naya zadacha, pos-
kol'ku  pravaya granica odnoj stroki v pamyati  prodolzhaetsya  levoj
granicej sleduyushchej stroki. Sdvig vsego soderzhimogo videobufera na
160  bajt vverh po pamyati (80 simvolov v stroke * 2 bajta na sim-
vol) privodit k sdvigu ekrana vniz na odnu stroku. Esli Vy pishete
svoyu  sobstvennuyu  proceduru sdviga ekrana,  ispol'zuyushchuyu  pryamoe
otobrazhenie v pamyat', to ne  zabyvajte  ob interferencii, kotoraya
voznikaet na cvetnom displee i PCjr.  |ta problema obsuzhdaetsya  v
[4.3.1]. Obychnoe reshenie etoj problemy sostoit v proverke status-
nogo  bajta,  ozhidaya poka on razreshit zapis' v  videobufer.   Vam
pridetsya poeksperimentirovat', chtoby opredelit' skol'ko dannyh Vy
mozhete zapisat' za odin cikl.
   Drugoe  reshenie etoj problemy sostoit v vyklyuchenii  ekrana  na
vremya operacii sdviga, a zatem v ego vosstanovlenii.  "Vyklyuchenie
ekrana" podrazumevaet, chto vyvod soderzhashchihsya v videobufere  dan-
nyh zapreshchen, no sam bufer pri etom  ne izmenyaetsya.  |tot process
ispol'zuetsya funkciej sdviga BIOS, ispol'zovannoj vyshe.  Hotya eto
ne ochen' priyatno dlya  glaz,  no  vse-taki  ne  tak ploho, kak uzhe
upominavshayasya interferenciya.
   Dlya  vyklyucheniya  ekrana u cvetnogo graficheskogo  displeya  nado
sbrosit' bit 3 porta s adresom  3D8H.   Izmenenie bita nazad na 1
momental'no vklyuchaet ekran obratno.  |tot adres porta  sootvetst-
vuet registru vybora rezhima cvetnogo graficheskogo adaptora.  |tot
odnobajtnyj registr tol'ko dlya zapisi, poetomu programma ne mozhet
prosto prochitat' ego, izmenit'  znachenie  bita 3 i vernut' prochi-
tannyj  bajt.  Vmesto etogo Vam neobhodimo opredelit' takzhe  pra-
vil'nuyu ustanovku vseh ostal'nyh bitov (perechislennyh v [4.1.2]).
Dlya  PCjr  etot bit raspolozhen v registre  upravleniya  rezhimom  1
massiva vorot displeya. V [4.1.1]  ob®yasneno kak poluchit' dostup i
zaprogrammirovat' etot registr.





   Gorizontal'nyj sdvig inogda trebuetsya v special'nyh programmah
obrabotki teksta, takih kak  tekstovye  redaktory.   Operacionnaya
sistema  ne imeet dlya etogo special'nyh sredstv.  Po etoj prichine
dannaya  zadacha nemnogo slozhnee chem vertikal'nyj sdvig - no  nesu-
shchestvenno.  Rassmotrim sluchaj, kogda Vy hotite, chtoby ekran sdvi-
galsya  vlevo  na 5 pozicij.  Pri etom levye 5 stolbcov  ischeznut,
ves' ostal'noj tekst sdvigaetsya vlevo,  a samye pravye 5 stolbcov
dolzhny  byt' ochishcheny.  Poskol'ku videobufer predstavlyaet iz  sebya
odnu dlinnuyu stroku, to esli  kazhdyj simvol bufera sdvinut' na 10
bajtov  vniz, to summarnyj effekt budet sostoyat' v tom, chto samye
levye 5 simvolov kazhdoj stroki  budut  peredvinuty  v poslednie 5
pozicij predydushchej stroki.  Takim obrazom, ves' ekran budet sdvi-
nut vlevo na 5 pozicij,  peredvigaya  5 nenuzhnyh stolbcov v pravuyu
chast'  ekrana.   Vse chto posle ostaetsya - eto ochistit'  pravye  5
stolbcov. |to legko delaetsya  s  pomoshch'yu  procedury vertikal'nogo
sdviga  [4.5.1], kotoraya mozhet vypolnyat'sya dlya lyuboj chasti ekrana
i kotoraya  ochishchaet  ukazannuyu  oblast'  esli  ukazat'  sdvig na 0
strok. Risunok 4-6 illyustriruet etot metod.

   Nizkij uroven'.

   V etom primere osushchestvlyaetsya sdvig na 5 pozicij vlevo.  Legko
izmenit' ego dlya sdviga vpravo  ili  dlya drugogo znacheniya pozicij
sdviga. Pri ispol'zovanii pryamogo otobrazheniya v pamyat' etot metod
daet prakticheski momental'nyj sdvig ekrana.

;---sdvigaem vse vniz na 10 bajtov
      MOV  AX,0B000H      ;ukazyvaem na bufer monohromnogo
      MOV  ES,AX          ;displeya
      MOV  DS,AX          ;
      MOV  SI,10          ;sdvigaem iz SI ...
      MOV  DI,0           ;... v DI
      MOV  CX,1995        ;sdvigaem vse krome poslednih 5 bajt
REP   MOVSW               ;osushchestvlyaem sdvig
;---ochishchaem pravyj kraj
      MOV  AH,6           ;funkciya vertikal'nogo sdviga
      MOV  AL,0           ;sdvig na 0 strok chistit okno
      MOV  CH,0           ;stroka levogo verhnego ugla
      MOV  CL,75          ;stolbec levogo verhnego ugla
      MOV  DH,24          ;stroka pravogo nizhnego ugla
      MOV  DL,79          ;stolbec pravogo nizhnego ugla
      MOV  BH,7           ;atribut dlya ochishchaemyh pozicij
      INT  10H            ;chistim okno





   Poskol'ku vse videosistemy,  krome monohromnogo displeya, imeyut
dostatochno  pamyati  dlya neskol'kih videobuferov, to  odnovremenno
mogut byt' skonstruirovany  neskol'ko  ekranov, kazhdyj iz kotoryh
mozhet byt' vyveden v nuzhnyj moment.  Vmesto togo, chtoby  peredvi-
gat' dannye  v  videopamyati,  monitor  posylaet  dannye iz drugoj
oblasti  videopamyati.  CHislo dostupnyh stranic mozhet  menyat'sya  v
zavisimosti ot videosistemy i  rezhima  displeya.  Privodim kratkuyu
svodku:

   Rezhim     Tip               CHislo stranic     Nachalo bufera

     0     alfavitnocifrovoj         8               B800
     1     alfavitnocifrovoj         8               B800
     2     alfavitnocifrovoj         8               B800
     3     alfavitnocifrovoj         8               B800
     4     graficheskij               1               B800
     5     graficheskij               1               B800
     6     graficheskij               1               B800
     7     alfavitnocifrovoj         1/8             B800
     8     graficheskij            peremennoe         B800
     9     graficheskij            peremennoe         B800
     A     graficheskij            peremennoe         B800
     D     graficheskij              2/4/8            A000
     E     graficheskij              1/2/4            A000
     F     graficheskij               1/2             A000
    10     graficheskij               1/2             A000

Rezhimy  8-A - graficheskie rezhimy PCjr; chislo stranic dlya nih  me-
nyaetsya v zavisimosti ot togo, skol'ko operativnoj pamyati otvedeno
pod videobufer. Razmer stranicy raven 2K ili 4K dlya alfavitnocif-
rovyh rezhimov, 32K -  dlya  chetyreh  cvetov pri vysokom razreshenii
ili 16 cvetov pri umerennom razreshenii i 16K - dlya vseh ostal'nyh
rezhimov.  Rezhimy D-10 podderzhivayutsya EGA.  Kolichestvo stranic me-
nyaetsya v zavisimosti ot ustanovlennoj pamyati.  Rezhimy F i 10 tre-
buyut nalichiya ne menee 128K pamyati. Rezhim 7 razreshaet odnu strani-
cu dlya monohromnogo adaptora i 8 stranic dlya EGA.
   Monohromnyj  adaptor ne imeet pamyati dlya dopolnitel'nyh  stra-
nic.  Odnako net nikakih prichin, po kotorym chast' osnovnoj pamyati
nel'zya  bylo  by ispol'zovat' kak bufer displeya.  V  etom  sluchae
stranichnaya  organizaciya  osushchestvlyaetsya  za  schet bystrogo obmena
vsego  soderzhimogo bufera v pamyati s videobuferom (adres kotorogo
B000:0000).  Bufer  v  osnovnoj  pamyati  mozhno  rassmatrivat' kak
"psevdostranicu".  Hotya eto i ne nastoyashchee razbienie na stranicy,
no rezul'tat budet pochti takoj  zhe,  esli dlya peresylki dannyh Vy
budete ispol'zovat' assemblernuyu proceduru.
   Pri  ispol'zovanii stranic nado pozabotit'sya o tom, chtoby ope-
racii vyvoda na ekran napravlyalis'  na nuzhnuyu stranicu. Programma
ne  obyazana vyvodit' dannye na tu stranicu, kotoraya v dannyj  mo-
ment izobrazhaetsya na ekrane.  Na samom dele, chasto naoborot zhela-
tel'no  konstruirovat'  ekran "za kulisami", a zatem  momental'no
vyvodit' uzhe gotovoe  izobrazhenie.  |tot  metod osobenno polezen,
kogda neobhodimo konstruirovat' slozhnyj vyvod v Bejsike, u  koto-
rogo vyvod ochen'  medlennyj.  BIOS  hranit v svoej oblasti dannyh
odnobajtnuyu peremennuyu, ukazyvayushchuyu, kakaya iz stranic vyvoditsya v
dannyj moment.  Diapazon znachenij etoj peremennoj ot 0 do 7.  Ona
raspolozhena po adresu 0040:0062.


   Vysokij uroven'.

   Bejsik  ispol'zuet  komandu SCREEN dlya ustanovki stranicy,  na
kotoruyu budet idti vyvod (aktivnoj stranicy) i vyvodimoj stranicy
(vidimoj  stranicy).  Stranicy numeruyutsya ot 0 do 3 dlya tekstov s
80 simvolami v stroke i ot 0 do 7 dlya 40-simvol'nyh. Tretij para-
metr   za  komandoj  SCREEN  ustanavlivaet   aktivnuyu   stranicu.
SCREEN,,2 privodit k tomu, chto vse operatory PRINT budut rabotat'
so stranicej 2.  CHetvertyj parametr ustanavlivaet vidimuyu strani-
cu.  SCREEN,,,1 privodit  k  tomu,  chto na ekran budet vyvodit'sya
stranica 1.  Kogda vidimaya stranica ne ukazyvaetsya, to  avtomati-
cheski prinimaetsya, chto ona sovpadaet s aktivnoj.
   Dlya vydeleniya pamyati pod  stranicy na PCjr ispol'zuetsya opera-
tor CLEAR.  |tot operator ustanavlivaet obshchee kolichestvo  pamyati,
otvodimoe pod bufer ekrana, kotoroe pri starte ravno 16384 bajta.
CHtoby   dobavit'   vtoruyu   stranicu   razmerom   16K,   napishite
CLEAR,,,32768. Dobavochnye  tekstovye stranicy trebuyut 4096 bajtov
kazhdaya.   Pri  uslovii, chto takim obrazom byla  otvedena  pamyat',
komandy operatora SCREEN dlya  raboty  so stranicami rabotayut opi-
sannym obrazom.  Tol'ko PCjr imeet dobavochnyj parametr  operatora
SCREEN, kotoryj stiraet stranicu (t.e. perevodit ee v cvet fona).
Detali  opisany v rukovodstve po Bejsiku.  Operator  PCOPY  takzhe
unikalen dlya PCjr. On  kopiruet  izobrazhenie  iz odnoj stranicy v
druguyu.  Naprimer, PCOPY 2,1 celikom kopiruet stranicu 2 na stra-
nicu 1.
   Hotya monohromnyj adaptor ne imeet  pamyati dlya stranic displeya,
odnako  imeetsya  sposob ustroit'  svoego  roda  "psevdostranicy".
Nizheprivedennaya procedura  na  mashinnom  yazyke rassmatrivaet blok
pamyati  kak displejnuyu stranicu.  Pri vyzove etoj  procedury  ona
obmenivaet soderzhimoe videobufera s soderzhimym etoj oblasti pamya-
ti.   V  rezul'tate my imeem kak by dve displejnye stranicy.   (V
prilozhenii G ob®yasnyaetsya kak  vklyuchat'  podprogrammy  na mashinnom
yazyke v programmy na Bejsike.)
   Vy dolzhny otvesti blok pamyati razmerom 4000 bajt dlya psevdost-
ranicy, pomimo pamyati, soderzhashchej  programmu na mashinnom yazyke. V
primere  blok  nachinaetsya s adresa segmenta  &H2000, a  procedura
pomeshchena po adresu &H2200.   Segmentnyj  adres bloka soderzhitsya v
9-m i 10-m bajtah mashinnogo koda i Vy legko mozhete izmenit'  ego.
Vidno, chto adres  &H2000  predstavlen  kak &H00, &H20 v operatore
DATA.  |to sledstvie togo, chto mladshie cifry vsegda razmeshchayutsya v
mladshih yachejkah pamyati. Esli Vy hotite razmestit' blok, skazhem po
adresu 1234:0000, to nado izmenit' bajty 9 i 10 na &H34, &H12.
   Vam  mozhet  potrebovat'sya ochistit'  psevdostarnicu  ot  vsyakoj
erundy, ostavshejsya ot  drugih  programm.   V  strokah 230-260 eto
dostigaetsya  za schet zasylki simvola probela (ASCII 32) v  kazhdyj
bajt (32 sluzhit "normal'nym" bajtom  atributov).  Programma mozhet
osushchestvlyat'  vyvod na ekran obychnym obrazom, a zatem  perenosit'
soderzhimoe na psevdostranicu.   No esli hotite, to Vy mozhete osu-
shchestvlyat' vyvod pryamo na psevdostranicu, ispol'zuya pryamoe otobra-
zhenie v pamyat'.


100 '''mashinnyj kod
110 DATA &H1E, &H06, &HB8, &H00, &HB0, &H8E, &HC0
120 DATA &HB8, (3&H00, &H20), &H8E, &HD8, &HBF, &H00
130 DATA &H00, &HBE, &H00, &H00, &HFC, &HB9, &HD0
140 DATA &H07, &H26, &H8B, &H1D, &HAD, &HAB, &H89
150 DATA &H5D, &HFE, &HE2, &HF6, &H07, &H1F, &HCB
160 '''pomeshchaem kod v pamyat'
170 DEF SEG = &H2200   'ukazyvaem adres procedury
180 FOR N = 0 TO 34    'nachinaem s pervogo bajta
190 READ Q             'chitaem bajt procedury
200 POKE N,Q           'pishem ego v pamyat'
210 NEXT               '
220 '''chistim psvedostranicu
230 DEF SEG = &H2000   'adres nachala psevdostranicy
240 FOR N = 0 TO 3999  'dlya kazhdogo simvola i atributa
250 POKE N,32          'pomeshchaem kod 32
260 NEXT               'poka ne ochistim ves' bufer

500 '''pishem pryamo v psevdostranicu
510 DEF SEG = &H2000   'ukazyvaem na ee adres
520 S$ = "PSEUDOPAGE"  'vyvodim slovo posredi stranicy
530 M = LEN(S$)        'poluchaem dlinu stroki
540 FOR N = 1 TO M     'dlya kazhdogo simvola stroki
550 POKE N*2+2000, ASC(MID$(S$,N,1))   'pomeshchaem ego v bufer
560 NEXT               '

600 '''teper' ispol'zuem proceduru
610 PRINT "SCRREN 1"   'pechataem soobshenie na ekran
620 DEF SEG = &H2200   'ukazyvaem na proceduru
630 PSEUDOPAGE = 0     'nachinaem s nachala procedury
640 CALL PSEUDOPAGE    'obmenivaem stranicy
650 CALL PSEUDOPAGE    'povtoryaem obmen
660 ...

   Srednij uroven'.

   Funkciya 5 preryvaniya 10H vybiraet tekushchuyu stranicu displeya dlya
vyvoda. Nado prosto pomestit' nomer stranicy v AL:

;---ustanovka vidimoj stranicy
   MOV  AH,5       ;nomer funkcii
   MOV  AL,2       ;nomer stranicy (nachinaya s 0)
   INT  10H        ;ustanavlivaem stranicu

Odnako eta funkciya  ne  ustanavlivaet  stranicu, na kotoruyu budet
idti  vyvod.  Lyuboe iz preryvanij BIOS, kotorye vyvodyat na  ekran
(funkcii preryvaniya 10H), trebuet chtoby nomer stranicy byl ukazan
v  kachestve vhodnogo parametra v odnom iz registrov.  Odnako  vse
preryvaniya vyvoda na ekran MS  DOS pishut na tekushchuyu vidimuyu stra-
nicu.   Takim obrazom, dlya "zakulisnyh" operacij  Vam  neobhodimo
pol'zovat'sya preryvaniem 10H.
   Dlya polucheniya informacii  o  tekushchej  stranice  nado vypolnit'
funkciyu  F  preryvaniya 10H, kotoraya  vozvrashchaet  status  displeya.
Nomer stranicy pri etom vozvrashchaetsya v BH.


   Nizkij uroven'.

   Displejnye stranicy vybirayutsya  za schet izmeneniya tochki video-
pamyati,  nachinaya s kotoroj monitor prinimaet dannye.   |ta  tochka
pamyati ustanavlivaetsya registrami 12 (starshij bajt) i 13 (mladshij
bajt)  mikroshemy 6845, kotorye nazyvayutsya registrami  startovogo
adresa. Znacheniya adresov razdela stranic dlya bufera, nachinayushchego-
sya s B800 takie:

                       40 simvolov            80 simvolov
   stranica 0             0000H                  0000H
            1             0400H                  0800H
            2             0800H                  1000H
            3             0C00H                  1800H
            4             1000H
            5             1400H
            6             1800H
            7             1C00H
V  [4.1.1]  ob®yasnyaetsya kak programmirovat'  registry  mikroshemy
6845, a v [4.5.4] soderzhitsya  primer  programmirovaniya startovogo
adresa.   V  poslednem primere nado prosto prisvoit' BX  odno  iz
znachenij vysheprivedennoj  tablicy.   Konechno, pri etom ustanavli-
vaetsya tol'ko vyvodimaya stranica. Dlya zapisi v opredelennuyu stra-
nicu na nizkom urovne nado  ispol'zovat' odno iz znachenij tablicy
v  kachestve  smeshcheniya v videobufere pri pryamom otobrazhenii v  pa-
myat'.
   Poskol'ku pryamoe otobrazhenie v  pamyat'  rabotaet ochen' bystro,
to  illyuziya stranic mozhet byt' legko sozdana na monohromnom disp-
lee.  Vydelite blok razmerom  4000  bajtov dlya hraneniya stranicy.
Hotya monohromnyj adaptor ne mozhet neposredstvenno chitat' iz obych-
noj pamyati, soderzhimoe etogo bufera  i videobufera mozhno obmenyat'
nastol'ko bystro, chto nikto ne zmetit raznicy. Sleduyushchaya procedu-
ra obmenivaet soderzhimoe etih dvuh oblastej.
;---v segmente dannyh
PPAGE  DW   2000  DUP(720H)  ;zapolnyaem bufer probelami

;---peresylka mezhdu psevdostranicej i videobuferom
            MOV  AX,0B000H   ;ukazyvaem na videobufer
            MOV  ES,AX       ;
            MOV  AX,SEG PPAGE  ;ukazyvaem na psevdostranicu
            MOV  DS,AX       ;
REPEAT:     MOV  DI,0        ;DI na nachalo videobufera
            MOV  SI,OFFSET PPAGE  ;SI na nachalo psevdostranicy
            CLD              ;napravlenie vpered
            MOV  CX,2000     ;budem peresylat' 2000 slov
NEXT_WORD:  MOV  BX,ES:[DI]  ;berem slovo iz videobufera v BX
            LODSW            ;slovo iz psevdostranicy v AX
            STOSW            ;slovo iz AX v videobufer
            MOV  DS:[DI]-2,BX  ;slovo iz BX v psevdostranicu
            LOOP NEXT_WORD   ;

   PCjr hranit registr stranicy v porte  s adresom 3DFH. Znachenie
bitov etogo registra sleduyushchee:

   bity 2-0   kakaya stranica vyvoditsya (ot 0 do 7)
        5-3   kakaya stranica pishetsya (ot 0 do 7) pri vyvode
              po adresu segmenta B800H


        7-6   = 00 dlya vseh tekstovyh rezhimov
              = 01 dlya graficheskih rezhimov s 16K
              = 11 dlya graficheskih rezhimov s 32K




   Poskol'ku stranicy teksta prilegayut drug k drugu v  videobufe-
re, to nebol'shoj tekstovyj massiv mozhet celikom pomeshchat'sya v etoj
pamyati.  V etom sluchae tekst sdvigat'sya vverh i vniz po ekranu ne
peredvigayas' real'no v bufere.  Vmesto etogo ekran nachinaet poka-
zyvat'  soderzhimoe bufera, nachinaya s razlichnyh tochek i tem  samym
sozdavaya illyuziyu sdviga. |tot  metod  nazyvaetsya apparatnym sdvi-
gom.
   Apparatnyj  sdvig  dostigaetsya za  schet  izmeneniya  startovogo
adresa displeya, kotoryj yavlyaetsya  chislom, ukazyvayushchim na simvol v
videobufere,  kotoryj budet vyvodit'sya v levom verhnem uglu ekra-
na.  Dobavlenie 80 k  etomu  chislu  "sdvigaet" ves' ekran na odnu
stroku vverh, a vychitanie 80 - na odnu stroku vniz. V rezhime s 40
simvolami v stroke nado vmesto 80 pribavlyat' ili vychitat' 40.  Na
ris. 4-7 privedena diagramma apparatnogo sdviga.
   Otmetim, chto registr startovogo adresa ne schitaet bajty  atri-
butov, poetomu Vy dolzhny  vychislyat' adresa pamyati po-drugomu, chem
pri pryamom otobrazhenii v pamyat'. Imejte takzhe vvidu, chto nesmotrya
na nalichie razryvov  pamyati  mezhdu  granicami  stranic (96 bajtov
mezhdu 80-simvol'nymi stranicami i 48 bajtov mezhdu  40-simvol'nymi
stranicami) mikroshema 6845 propuskaet eti oblasti i sdvig nepre-
ryvno proishodit s odnoj stranicy na sleduyushchuyu.  Apparatnyj sdvig
proishodit nastol'ko bystro, chto Vam  mozhet okazat'sya neobhodimym
vstavit' proceduru zaderzhki, chtoby pol'zovatel' imel  vozmozhnost'
uvidet' naskol'ko sdvinulsya ekran.
   BIOS hranit  tekushchee  znachenie  registra  startovogo  adresa v
peremennoj  v svoej oblasti dannyh.  |ta  dvuhbajtnaya  peremennaya
raspolozhena po adresu 0040:004EH.

   Nizkij uroven'.

   Startovyj adres soderzhitsya v  registrah 12 (starshij bajt) i 13
(mladshij bajt) mikroshemy 6845. V [4.1.1] ob®yasnyaetsya rabota etoj
mikroshemy.  Prezhde  chem  adresuemyj  bajt  napravlyaetsya v port s
adresom  3D5H,  neobhodimo poslat' nomer adresuemogo  registra  v
port 3D4H. V dannom primere  ekran sdvigaetsya vverh na odnu stro-
ku. Peremennaya START_ADDRESS soderzhit adres pervogo simvola teku-
shchej verhnej stroki ekrana.

   MOV  BX,START_ADDRESS  ;nachinaem s nachala bufera
   ADD  BX,80             ;sdvigaem na 1 stroku (80 simvolov)
   MOV  DX,3D4H           ;vyvod v adresnyj registr
   MOV  AL,12             ;adresuem registr 12
   OUT  DX,AL             ;posylaem zapros
   INC  DX                ;teper' vyvodim v komandnyj registr
   MOV  AL,BH             ;starshee slovo v AL
   OUT  DX,AL             ;posylaem ego v registr 12
   DEC  DX                ;obratno k adresnomu registru
   MOV  AL,13             ;adresuem registr 13
   OUT  DX,AL             ;posylaem zapros
   INC  DX                ;snova komandnyj registr
   MOV  AL,BL             ;mladshee slovo v AL
   OUT  DX,AL             ;posylaem v registr 13







   Vse  diski, kak gibkie, tak i zhestkie, organizovany odinakovym
obrazom.  Poverhnost' diska  razdelena na ryad koncentricheskih ko-
lec,  nazyvaemyh dorozhkami, a dorozhki delyatsya radial'no na sekto-
ra.  Naprimer, standartnaya  disketa s diametrom 5 1/4 dyujma imeet
40  dorozhek  i v sisteme MS DOS 2.0 kazhdaya dorozhka razbita  na  9
sektorov (15  sektorov  na  diskete  emkost'yu  1.2 Mbajta i 17 na
fiksirovannom  diske).  Razmer sektora 512 bajt, i 512  bajt *  9
sektorov * 40 dorozhek *  2  storony  daet v itoge emkost' diskety
360K.   Vse tipy diskov ispol'zuyut razmer sektora 512  bajt v  MS
DOS.
   Fajl raspredelen po takomu  kolichestvu sektorov, kotoroe neob-
hodimo, chtoby vmestit' ego.  Tol'ko neskol'ko sektorov na vneshnem
obode diskety  zarezervirovany  dlya  special'nyh  nuzhd. Ostal'nye
dostupny  na osnove pravila "pervyj podoshel - pervogo  obsluzhat".
|to oznachaet, chto po mere zapolneniya diska dannymi sektora poste-
penno zapolnyayutsya po napravleniyu k centru diska.  Pri unichtozhenii
fajla sektora osvobozhdayutsya i so vremenem  svobodnye oblasti sta-
novyatsya  razbrosannymi po disku, razbivaya novye fajly i  zamedlyaya
dostup k nim dlya chteniya i zapisi.
   Fiksirovannye diski imeyut nekotorye  special'nye harakteristi-
ki.   CHasto oni sostoyat iz dvuh ili bolee parallel'nyh plastin, u
kazhdoj iz kotoryh est' dve golovki,  chtoby chitat' obe ih storony.
Vse dorozhki, raspolozhennye na dannom rasstoyanii ot centra, vmeste
nazyvayutsya  cilindrom.   Poskol'ku  golovki vseh diskov dvigayutsya
tandemom,  to dostigaetsya ekonomiya peremeshchenij esli zapolnyat' vse
dorozhki odnogo  cilindra,  prezhde  chem  perehodit'  k sleduyushchemu.
Gruppy cilindrov mogut otnosit'sya k razlichnym operacionnym siste-
mam.  Programma DOS FDISK mozhet  razbivat'  fiksirovannyj disk na
neskol'ko razdelov (do chetyreh) raznogo razmera.  Po etoj prichine
parametry fiksirovannogo diska mogut sil'no otlichat'sya.
   Diskovye sektora opredelyayutsya  magnitnoj  informaciej, kotoruyu
zapisyvaet utilita formatizacii diska.  Informaciya vklyuchaet iden-
tifikacionnyj nomer kazhdogo sektora.   BIOS numeruet sektora 1-8,
1-9  ili 1-15, v zavisimosti ot emkosti diska.  Dorozhki ne marki-
ruyutsya, vmesto etogo  oni  opredelyayutsya  mehanicheski  po smeshcheniyu
golovki chteniya/zapisi ot vneshnego kraya diska.  Dorozhki numeruyutsya
ot 0 do 39 dlya disket diametrom 5 1/4 dyujma, a dlya diskov bol'shej
emkosti ih mozhet byt' bol'she.  Diskovye funkcii BIOS obrashchayutsya k
opredelennomu sektoru, ukazyvaya nomera dorozhki i sektora.  Odnako
funkcii DOS rassmatrivayut vse sektora diska, kak odnu cep', koto-
raya numeruetsya podryad, nachinaya ot  0, poetomu kazhdyj sektor imeet
svoj logicheskij nomer sektora.
   Dlya disket pervyj sektor (dorozhka 0, sektor 1) soderzhit zapis'
nachal'noj zagruzki, kotoraya yavlyaetsya nebol'shoj programmoj, pozvo-
lyayushchej komp'yuteru schitat' s diskovogo nakopitelya ostal'nye  chasti
MS DOS. Zatem idut dve kopii  tablicy  razmeshcheniya fajlov, kotorye
soderzhat informaciyu o raspredelenii diskovogo prostranstva  (vto-
raya kopiya hranitsya iz soobrazhenij bezopasnosti).  Zatem idet kor-
nevoj katalog, kotoryj soderzhit spisok fajlov i ssylok na  podka-
talogi, a takzhe ukazyvaet  v  kakom  meste  diska oni nachinayutsya.
Nakonec,  dalee  idut dve nebol'shie programmy  DOS  IBMBIO.COM  i
IBMDOS.COM, kotorye schityvayutsya pri starte i obespechivayut komp'yu-


ter  vozmozhnostyami  neobhodimymi dlya nahozhdeniya i zagruzki  fajla
COMMAND.COM, kotoryj nesomnenno  yavlyaetsya  osnovnoj chast'yu opera-
cionnoj sistemy.

   Fiksirovannye  diski  imeyut glavnuyu zapis'  zagruzki,  kotoraya
soderzhit tablicu razdelov,  pozvolyayushchuyu razdelit' disk mezhdu nes-
kol'kimi operacionnymi sistemami.  Tablica razdelov soderzhit  in-
formaciyu o tom, gde na diske  nachinaetsya razdel DOS, a takzhe per-
vyj sektor kakogo razdela soderzhit zapis' nachal'noj zagruzki.   V
ostal'nom razdel organizovan tak zhe, kak i disketa.




   Disk ispol'zuet tablicu  razmeshcheniya fajlov (FAT) dlya otvedeniya
diskovogo  prostranstva fajlam i hraneniya informacii o  svobodnyh
sektorah. Iz soobrazhenij bezopasnosti na vseh diskah hranyatsya dve
kopii  FAT.   Oni hranyatsya posledovatel'no, v  sektorah s  samymi
mladshimi dostupnymi logicheskimi  nomerami,  nachinaya so storony 0,
dorozhki  0,  sektora  2 (sektor 1 takzhe zanyat  zapis'yu  nachal'noj
zagruzki). CHislo sektorov, zanimaemyh FAT opredelyaetsya razmerom i
tipom  diska.  Otmetim, chto v MS DOS 3.0 razmer zapisi FAT  mozhet
byt' 16 bitov dlya fiksirovannogo diska. Zdes' my budem rassmatri-
vat' tol'ko 12-bitnye zapisi; dlya polucheniya informacii o 16-bito-
vyh zapisyah, smotrite Tehnicheskoe rukovodstvo po MS DOS.
   Tablica  razmeshcheniya fajlov hranit informaciyu o kazhdom klastere
sektorov na diske. Klaster eto gruppa standartnyh sektorov razme-
rom  512 bajt (nezavisimo ot tipa diska MS DOS vsegda rabotaet  s
512-bajtnymi  sektorami).   Gruppa  sektorov  ispol'zuetsya, chtoby
umen'shit'  razmer FAT.  Odnako bol'shie klastery, ispol'zuemye  na
fiksirovannom diske naprasno  rashoduyut diskovoe prostranstvo pri
zapisi  malen'kih fajlov (utilita razmerom 500 bajt beret 4K dis-
kovogo prostranstva). Imeetsya nabor razmerov klasterov i razmerov
FAT, ispol'zuemyh v IBM PC:

   Tip diska         Sektorov na klaster    Razmer FAT

  disketa 160K                1                  1
  disketa 180K                1                  1
  disketa 320K                2                  2
  disketa 360K                2                  2
  disketa 1.2M                1                  7
  vinchester 10M               8                  8
  vinchester 20M               4                 40

   Pri  bol'shem  razmere klastera naprasno  rashoduetsya  diskovoe
prostranstvo, no kogda bol'shie diski imeyut malyj razmer klastera,
to  tablica  razmeshcheniya fajlov stanovitsya slishkom  bol'shoj.   Pri
rabote s diskami DOS zagruzhaet kopiyu FAT v pamyat', po vozmozhnosti
sohranyaya ee tam, poetomu pri  bol'shom  razmere FAT mozhet rashodo-
vat'sya  mnogo operativnoj pamyati.  Poskol'ku bol'shinstvo AT imeyut
dostatochno mnogo pamyati,  to  dlya  nih  priemlemy namnogo bol'shie
FAT.  Poetomu dlya 20M vinchestera vzyaty men'shie razmery klasterov,
chem dlya 10M,  obespechivaya  ekonomiyu  diskovogo  prostranstva. Dlya


disket  emkost'yu 1.2M vybran klaster razmerom v 1 sektor, tak kak
ih osnovnoe naznachenie sostoit v hranenii kopij zhestkogo diska, a
sledovatel'no kompaktnost' ochen' vazhna.
   Kazhdaya poziciya v tablice razmeshcheniya fajlov sootvetstvuet opre-
delennoj pozicii klastera na diske. Obychno fajl zanimaet neskol'-
ko klasterov i zapis' v kataloge fajlov soderzhit nomer startovogo
klastera, v kotorom  zapisano  nachalo  fajla.  Prosmotrev poziciyu
FAT,  sootvetstvuyushchuyu pervomu klasteru, DOS nahodit nomer klaste-
ra, v kotorom hranitsya sleduyushchaya porciya  etogo fajla. |tomu klas-
teru  sootvetstvuet  svoya zapis' v FAT,  kotoraya v  svoyu  ochered'
soderzhit nomer  sleduyushchego  klastera  v  cepochke.  Dlya poslednego
klastera,  zanyatogo fajlom FAT soderzhit znacheniya ot FF8H do FFFH.
Neispol'zuemym (ili osvobozhdennym)  klasteram zapisyvaetsya znache-
nie  000, a plohim sektoram - FF7H.  Nakonec, znacheniya ot FF0H do
FF7H pripisyvayutsya rezervnym klasteram.

   Nomer klastera soderzhit 3 shestnadcatirichnye  cifry, dlya hrane-
niya  kotoryh trebuetsya 1 1/2 bajta.  Dlya umen'sheniya razmerov  FAT
chisla dlya dvuh sosednih  klasterov hranyatsya v treh posledovatel'-
nyh bajtah tablicy. MS DOS avtomaticheski proizvodit vse neobhodi-
mye vychisleniya.
   Pervye tri bajta FAT  ne  ispol'zuyutsya  dlya nomerov klasterov.
Pervyj bajt soderzhit kod, opredelyayushchij tip diska (sm. [1.1.5]), a
sleduyushchie 2 bajta oba ravny  FFH.   Poskol'ku eti pozicii tablicy
zanyaty,  to klastery numeruyutsya, nachinaya s 2, prichem klastery 2 i
3 zanimayut vtoruyu trojku bajt tablicy.
   MS DOS 3.0 mozhet  sozdavat'  FAT  s  zapisyami razmerom 16 bit.
Takie  zapisi neobhodimy dlya fiksirovannyh diskov razmerom  bolee
10M, kotorye imeyut bol'she, chem 4086 klasterov.  Na ris. 5-1 poka-
zana svyaz' mezhdu FAT i klasterami na diske.
   Ochen' redko imeyutsya prichiny vnosit' izmeneniya pryamo v  tablicu
razmeshcheniya fajlov. MS DOS zabotitsya obo vseh fajlovyh operaciyah i
obespechivaet  procedury, analiziruyushchie tablicu na predmet nalichiya
svobodnogo prostranstva na diske.  Odnako dlya nekotoryh special'-
nyh celej, takih kak vosstanovlenie udalennyh fajlov ili  napisa-
nie drajvera blochnogo  ustrojstva, neobhodim pryamoj dostup k FAT.
Pri pryamom dostupe k FAT nado soblyudat' sleduyushchie pravila.

Dlya nahozhdeniya sleduyushchego klastera fajla:

1. Umnozh'te nomer klastera na 1.5.
2. Prochitajte 2 bajta s poluchennym smeshcheniem (okgruglyaya vniz).
3.  Esli nomer klastera chetnyj, to voz'mite mladshie 12 bit, inache
voz'mite starshie 12 bit.

Dlya preobrazovaniya nomera klastera v logicheskij nomer sektora:

1. Vychtite 2 iz nomera klastera.
2. Umnozh'te rezul'tat na chislo sektorov v klastere.

   Vysokij uroven'.

   V dannom primere chitaetsya FAT i  poredelyaetsya znachenie, hranya-
shcheesya dlya klastera nomer 6.  V [5.4.2] ob®yasnyaetsya nachal'nyj kod,


chitayushchij  sektora  FAT.  Rezul'tatom  yavlyaetsya  12-bitnoe  chislo,
predstavlennoe  v vide treh shestnadcatirichnyh cifr (4  bita  kazh-
daya), vozvrashchaemoe v vide stroki. V primere pary chisel, sostoyashchih
iz dvuh cifr, ob®edineny i v  kachestve  rezul'tata berutsya pravye
ili  levye  tri cifry.  Kogda Bejsik preobrazuet simvol v  16-nuyu
formu, to on vozvrashchaet tol'ko  odnu  cifru, esli pervaya byla nu-
lem,  poetomu udalennyj nol' dolzhen byt' vosstanovlen, chtoby etot
metod rabotal pravil'no.

100 '''chtenie sektorov FAT
110 DEFINT A-Z
120 DATA &H55, &H8B, &HEC, &H1E, &H8B, &H76, &H0C, &H8B
130 DATA &H04, &H8B, &H76, &H0A, &H8B, &H14, &H8B, &H76
140 DATA &H08, &H8B, &H0C, &H8B, &H76, &H06, &H8A, &H1C
150 DATA &H8E, &HD8, &H8B, &HC3, &HBB, &H00, &H00, &HCD
160 DATA &H25, &H59, &H1F, &H5D, &HCA, &H08, &H00
170 DEF SEG = &H1000     'pomeshchaem mashinnyj kod s etogo adresa
180 FOR N = 0 TO 38      'chitaem 39 bajtov dannyh
190 READ Q: POKE N,Q     'perenosim ih v pamyat'
200 NEXT                 '
210 READSECTOR = 0       'nachinaem proceduru s 1-go bajta
220 BUFFER = &H2000      'adres bufera priema dannyh
230 LOGICALNUMBER = 1    'nachal'nye sektora FAT
240 NUMBERSECTORS = 2    '2 sektora v FAT
250 DRIVE = 0            'chitaem nakopitel' A
260 CALL READSECTOR(BUFFER,LOGICALNUMBER,NUMBERSECTORS,DRIVE)
270 '''opredelyaem nomer sleduyushchego klastera fajla
280 DEF SEG = &H2000     'bufer, gde hranitsya FAT
290 CLUSTERNUMBER! = 6   'klaster nomer 6
300 C! = CLUSTERNUMBER!  'delaem kopiyu
310 C! = INT (C!*1.5)    'umnozhaem na 1.5 i okruglyaem
320 X = PEEK(C!)         'chitaem 2 bajta s etoj pozicii
330 Y = PEEK(C!+1)       '
340 X$ = HEX$(X): Y$ = HEX$(Y)  'perevodim v 16-nye stroki
350 IF LEN(X$) = 1 THEN X$ = "0"+X$  'delaem iz 2-simvol'nymi
360 IF LEN(Y$) = 1 THEN Y$ = "0"+Y$  '
370 H$ = Y$ + X$         'ob®edinyaem chisla v odnu stroku
380 '''proveryaem klaster na chetnost'
390 IF CLUSTERNUMBER! MOD 2 <> 0 THEN 420  'uhod, esli nechetnyj
400 NEXTCLUSTER$ = RIGHT$(H$,3)  'esli chetnyj, to pravye 3 cifry
410 GOTO 430
420 NEXTCLUSYER$ = LEFT$(H$,3)   'esli nechetnyj, to levye
430 PRINT NEXTCLUSTER$   'pechataem rezul'tat

   Srednij uroven'.

   Funkciya  DOS 1CH daet informaciyu o tablice razmeshcheniya  fajlov,
no ne daet samu FAT.  Pomestite  nomer  nakopitelya  v DL, gde 0 =
nakopitel'  po umolchaniyu, 1 = A, i t.d.  Pri vozvrate DX soderzhit
chislo klasterov v FAT, a CX - chislo  bajtov v sektore. DS:BX uka-
zyvaet  na bajt, soderzhashchij pervyj bajt FAT, t.e.  na kod, ukazy-
vayushchij tip diska; eti kody perechisleny v [1.1.5].


   Nizkij uroven'.

   Namnogo legche poluchit' dostup k FAT v yazyke assemblera.  Otme-
tim, chto umnozhenie nomera klastera  na 1.5 proizvoditsya kopirova-
niem  chisla, sdvigom kopii vpravo na 1 bit dlya deleniya popolam  i
slozheniem kopii s originalom.  |tot metod avtomaticheski okgrulyaet
rezul'tat vniz. Kod, schityvayushchij sektora FAT v pamyat', obsuzhdaet-
sya v [5.4.2].

;---v segmente dannyh
BUFFER    DB   1024  DUP(0)  ;otvodim mesto dlya 2 sektorov

;---chitaem FAT v pamyat'
          LEA  BX,BUFFER      ;ukazyvaem na bufer dannyh
          MOV  DX,1           ;logicheskij nomer sektora
          MOV  CX,2           ;2 sektora
          MOV  AL,0           ;nakopitel' A
          INT  25H            ;chitaem sektora
          POP  CX             ;vosstanavlivaem stek
;---poluchaem nomer klastera
          MOV  AX,3           ;nomer klastera v AX
          MOV  CX,AX          ;delaem kopiyu
          MOV  DX,AX          ;delaem vtoruyu kopiyu
          SHR  DX,1           ;delim vtoruyu kopiyu na 2
          ADD  CX,DX          ;skladyvaem mezhdu soboj
          ADD  BX,CX          ;dobavlyaem kak smeshchenie
          MOV  DX,[BX]        ;poluchaem 2 bajta iz etogo mesta
          TEST AX,1           ;nomer klastera nechetnyj?
          JNZ  ODD_CLUSTER    ;uhod, esli da
          AND  DX,0000111111111111B    ;poluchaem nomer
          JMP  SHORT CONTINUE   ;uhod cherez obrabotku nechetnogo
ODD_CLUSTER:   MOV  CL,4      ;podgotovka k sdvigu vpravo
          SHR  DX,CL          ;sdvigaem vniz starshie 12 bitov
CONTINUE:




   Hotya v sleduyushchem podrazdele ob®yaneno kak vosstanovit' situaci-
ciyu  pri  oshibke  iz-za nehvatki mesta na diske, no  net  luchshego
lekarstva, chem predusmotritel'nost'. Programma dolzhna kontroliro-
vat'  dostupnoe diskovoe prostranstvo i soobshchat'  pol'zovatelya  o
nehvatke mesta. Esli  mesta  ne  hvataet,  to  pol'zovatel' mozhet
vyjti iz programmy i ustranit' problemu bez poteri informacii.

   Vysokij uroven'.

   Sleduyushchaya  assemblernaya  podprogramma vozvrashchaet v  peremennuyu
CLUSTERS chislo svobodnyh  klasterov  na ukazannom diske. Nado po-
mestit'  nomer nakopitelya v DRIVENUM, gde 1 = A, 2 = B i t.d.   V
prilozhenii G ob®yasnyaetsya kak assemblernye podprogrammy vklyuchayutsya
v programmy na Bejsike.


 10 DEFINT A-Z         'ispol'zuem celye peremennye
 20 DRIVENUM = 1       'syuda pomeshchaem nomer nakopitelya
 30 CLUSTERS = 0       'inicializiruem peremennuyu
 40 DATA &H55, &H8B, &HEC, &H8B, &H76, &H06, &H8B
 50 DATA &H14, &HB4, &H36, &HCD, &H21, &H8B, &H7E
 60 DATA &H08, &H89, &H1D, &H5D, &HCA, &H04, &H00
 70 DEF SEG = &H1000   'pomeshchaem podprogrammu
 80 FOR N = 0 TO 20    'berem kazhdyj bajt
 90 READ Q: POKE N,Q   'chitaem ego i pomeshchaem v pamyat'
100 NEXT               '
110 FREESPACE = 0      'ukazatel' na nachalo procedury
120 CALL FREESPACE(CLUSTERS,DRIVENUM)  'vyzov procedury
130 PRINT "CLUSTERS: ";CLUSTERS   'pechat' chisla klasterov

   Srednij uroven'.

   Funkciya 36H preryvaniya 21H soobshchaet skol'ko imeetsya svobodnogo
prostranstva na diske.  Edinstvennyj  vhodnoj registr DL, kotoryj
dolzhen soderzhat' nomer nakopitelya.  Nakopitel' po umolchaniyu oboz-
nachaetsya 0, nakopitel' A - 1  i  t.d.   Pri  vozvrate BX soderzhit
chislo dostupnyh klasterov, AX - chislo sektorov v klastere, a CX -
kolichestvo bajt v sektore.  Nebol'shoe uprazhnenie v umnozhenii daet
zhelaemyj  rezul'tat.   V sleduyushchem primere  proveryaetsya,  chto  na
dvuhstoronnej  diskete   ostalos'   po  men'shej mere 2K diskovogo
prostranstva:

   MOV  AH,36H          ;nomer funkcii
   MOV  DL,1            ;nakopitel' A
   INT  21H             ;poluchaem informaciyu
   CMP  BX,2            ;imeetsya li 2 svobodnyh klastera?
   JL   RUNNING_OUT     ;esli net, to soobshchaem ob etom




   Programma  mozhet  pozhelat'  proverit' razmer fajla  po  raznym
prichinam.  Odna iz vozmozhnyh  prichin  sostoit v opredelenii chisla
zapisej,  soderzhashchihsya  v fajle.  Drugaya - v opredelenii  pozicii
konca fajla, s tem chtoby fajlovyj  ukazatel' byl ustanovlen verno
dlya dobavleniya v fajl novyh dannyh, bez izmeneniya sushchestvuyushchih.
   Konechno,  razmer fajla ustanavlivaetsya avtomaticheski  funkciej
DOS.  Inogda programma mozhet nuzhdat'sya v rezervirovanii diskovogo
prostranstva  dlya dal'nejshego ispol'zovaniya.  V etom sluchae  nado
otkryt' fajl v rezhime  pryamogo  dostupa  i  zapisat'  takoj nomer
zapisi, chtoby fajl imel dostatochnuyu dlinu.  Zapisi mezhdu "fiktiv-
noj" i real'no otnosyashchimisya k fajlu budut zapolneny temi dannymi,
kotorye  sluchajno  okazhutsya v diskovyh sektorah,  otvedennyh  dlya
fajla pri etoj operacii.

   Vysokij uroven'.

   V Bejsike funkciya LOF  (dlina  fajla)  vozvrashchaet tochnoe chislo
bajtov,  otvedennyh fajlu (preduprezhdaem, odnako, chto starye ver-
sii Bejsika - 1.h - vozvrashchayut chislo  128-bajtnyh blokov, ispol'-


zuemyh fajlom).  Fajl dolzhen byt' otkryt i ssylat'sya na nego nado
po nomeru, pod kotorym  byl  otkryt  fajl.   Format X = LOF(1). V
sleduyushchem  primere opredelyaetsya skol'ko 64-bajtnyh zapisej soder-
zhitsya v fajle, otkrytom kak #3:

100 OPEN "FILENAME" AS #3   'otkryvaem fajl
110 RECORDLEN = 64          'opredelyaem dlinu zapisi
120 NUMBREC = LOF(3)/RECORDLEN  'vychislyaem chislo zapisej

   Srednij uroven'.

   FCB funkciya 23H preryvaniya 21H soobshchaet chislo zapisej v fajle.
Esli  pripisat' fajlu dlinu zapisi v 1 bajt, to ego razmer  budet
vozvrashchen v bajtah.  DS:DX  dolzhny  ukazyvat' na upravlyayushchij blok
otkrytogo fajla. Zatem vyzovite funkciyu.  Esli fajl ne najden, to
v AL vozvrashchaetsya FF.  V protivnom sluchae v AL vozvrashchaetsya 0,  a
chislo zapisej pomeshchaetsya v pole nomera zapisi pryamogo dostupa FCB
(bajty 33-36). Dlya pravil'noj raboty pole dliny zapisi FCB dolzhno
byt' ustanovleno posle otkrytiya  fajla, no pered vyzovom funkcii;
eto dvuhbajtnoe pole raspolozheno po smeshcheniyu 14 v FCB.  Esli raz-
mer fajla netochno delitsya na  dlinu  zapisi,  to soobshchaemoe chislo
zapisej  okruglyaetsya  vverh.  Vot primer, v kotorom  ispol'zuetsya
dlina zapisi ravnaya 1:

;---opredelenie razmera fajla
   LEA  DX,FCB        ;DS:DX ukazyvaet na FCB
   MOV  BX,DX         ;kopiruem ukazatel' v BX
   MOV  CX,1          ;razmer zapisi v CX
   MOV  [BX]+14,CX    ;pishem v pole razmera zapisi FCB
   MOV  AH,23H        ;funkciya soobshchayushchaya razmer fajla
   INT  21H           ;vyzov funkcii
   MOV  AX,[BX]+33    ;poluchaem mladshuyu chast' razmera fajla
   MOV  CX,[BX]+35    ;poluchaem starshuyu chast' razmera fajla

   Mozhno takzhe ustanavlivat'  dlinu  fajla, ispol'zuya upravlyayushchie
bloki fajla.  Dlya etogo nado ispol'zovat' funkciyu zapisi bloka  s
pryamym dostupom, kotoraya  obsuzhdaetsya  v [5.4.5].  U etoj funkcii
imeetsya chastnyj sluchaj, kogda chislo zapisannyh zapisej ustanavli-

vaetsya ravnym nulyu, to dlina  fajla  ustanavlivaetsya ravnoj chislu
zapisej, ukazannomu v pole zapisi pryamogo dostupa.
   Metod,  ispol'zuyushchij deskriptor fajla (file handle)  ne  imeet
funkcii, kotoraya neposredstvenno  soobshchala by dlinu fajla, odnako
imeetsya  vozmozhnost' vychislit' razmer, peredvinuv ukazatel' fajla
s nachala na konec fajla. Pri otkrytii fajla ukazatel' fajla avto-
maticheski  ustanavlivaetsya na pervyj bajt fajla.  Ukazatel' fajla
peremeshchaetsya funkciej  42H  preryvaniya  21H.  Nado pomestit' v AL
kodovoe chislo 2, napralyayushchee ukazatel' na konec fajla.  V BX dol-
zhen byt' ukazan nomer fajla, a  CX:DX  soderzhit smeshchenie ot konca
fajla  do  pozicii, v kotoruyu dolzhen byt'  ustanovlen  ukazatel',
poetomu pomestite 0 v oba etih registra.  Zatem vyzovite funkciyu.
Pri vozvrate DX:AX budet soderzhat' novuyu poziciyu ukazatelya, otno-
sitel'no ego  predydushchej  pozicii  -  t.e.  budet soderzhat' dlinu


fajla (DX soderzhit starshij bajt).  Pri vozniknovenii oshibki budet
ustanovlen flag perenosa, a v AX  budet vozvrashcheno 1, esli nepra-
vilen nomer funkcii i 6, esli nepravilen nomer fajla. Ne zabud'te
zatem snova vernut' ukazatel' na nachalo fajla, esli eto neobhodi-
mo.  Pomestite 0 v AL, CX i DX i vyzovite funkciyu snova. Vot pri-
mer:

;---otkryvaem fajl
   LEA  DX,FILE_PATH     ;DS:DX ukazyvayut na put' fajla
   MOV  AL,0             ;otkryvaem dlya chteniya
   MOV  AH,3DH           ;funkciya otkrytiya fajla
   INT  21H              ;otkryvaem ego
   JC   OPEN_ERROR       ;proverka na oshibku
   MOV  HANDLE,AX        ;zapominaem nomer fajla
;---opredelyaem dlinu fajla
   MOV  AH,42H           ;funkciya peremeshcheniya ukazatelya
   MOV  AL,2             ;kod ustanovki na konec fajla
   MOV  BX,HANDLE        ;nomer fajla v BX
   MOV  CX,0             ;0 v CX i DX
   MOV  DX,0             ;
   INT  21H              ;sdvigaem ukazatel'
   JC   POINTER_ERROR    ;oshibka?
   MOV  FSIZE_HIGH,DX    ;zapominaem razmer fajla
   MOV  FSIZE_LOW,DX     ;




   Pri  popytke zapisi na polnyj disk mozhet proizojti krah  prog-
rammy. CHasto legko izbezhat' etogo, dazhe v Bejsike, proveriv pred-
varitel'no nalichie diskovogo prostranstva [5.1.2].  Odnako,  esli
oshibka proizoshla, to  postarajtes'  dat' pol'zovatelyu vozmozhnost'
ispravit'  ee.   Pozvol'te emu sohranit' tol'ko chast' dannyh  ili
steret' kakoj-nibud' drugoj  fajl  i  povtorit' popytku. Ili, eshche
bolee radikal'noe sredstvo, pozvol'te pol'zovatelyu vstavit'  dru-
guyu disketu. Poslednij  podhod  dolzhen  realizovyvat'sya s bol'shoj
ostorozhnost'yu. Snachala zakrojte vse otkrytye fajly. Zatem vydajte
zapros na smenu diskety.  Posle  togo,  kak pol'zovatel' soobshchit,
chto  novaya disketa na meste, sozdajte novyj fajl i zapishite  tuda
dannye.

   Vysokij uroven'.

   V Bejsike  nado  ustanovit'  proceduru  obrabotki  oshibok, kak
pokazano v [7.2.5].  Esli operator Bejsika delaet popytku  pisat'
na polnyj disk, to vozvrashchaetsya kod oshibki #61. Pri etom upravle-
nie  mozhet byt' peredano procedure obrabotki oshibok, kotoraya  in-
formiruet pol'zovatelya  o  probleme  i pozvolyaet emu spravit'sya s
nej, ne teryaya dannyh.


100 ON ERROR GOTO 5000     'razreshaem obrabotku oshibok
 .
 .
200 OPEN FNAME$ FOR OUTPUT AS #1  'otkryvaem fajl
210 FOR N = 1 TO ARRLEN    'nachinaem pisat' massiv na disk
220 PRINT #1, ARRAY$(N)    'zapisyvaem odin element
230 NEXT                   '
 .
 .
5000 IF ERR = 61 THEN 5100  'disk polon?
5100 IF ERR = ...           'drugie oshibki ...
 .
5100 '''vosstanovlenie pri perepolnenii diska
5110 BEEP: PRINT "Disk full - choose an option:"
5120 PRINT "(A) - Re-edit the file"
5130 PRINT "(B) - Delete some other file from disk"
5140 PRINT "(C) - Use different diskette"
 .       (zdes' idet procedura vosstanovleniya)
 .
5500 RESUME

   Srednij uroven'.

   Vse  funkcii  DOS, kotorye pishut na disk, vydayut  opredelennyj
kod oshibki pri popytke  zapisi  na  polnyj  disk. Vot svodka etih
kodov:

   Metod dostupa  Funkciya        Nazvanie            Kod oshibki

      FCB          15H      Posledovatel'naya zapis'    AL = 1
      FCB          22H      Pryamaya zapis'              AL = 1
      FCB          27H      Pryamaya zapis' bloka        AL = 1
   Deskriptor      40H      Zapis' v fajl/ustrojstvo   CX <> BX

Proveryajte  eti  oshibochnye usloviya posle kazhdoj zapisi  na  disk.
Poskol'ku kriticheskoj oshibki ne  proishodit, to vosstanovlenie ne
vyzyvaet  problem.   Nado tol'ko proveryat' na oshibku  kazhdyj  raz
kogda Vy vyzyvaete odnu iz etih funkcij  i sozdat' horoshuyu proce-
duru obrabotki oshibok po Vashemu vkusu.




   Kazhdyj disk imeet odin kornevoj katalog, s kotorogo nachinaetsya
poisk vseh ostal'nyh katalogov.  Kornevoj katalog mozhet soderzhat'
elementy,  ukazyvayushchie  na  podkatalogi, kotorye v  svoyu  ochered'
mogut soderzhat' ssylki na drugie podkatalogi, obrazuya drevovidnuyu
strukturu katalogov. Kornevoj katalog vsegda raspolozhen v oprede-
lennyh sektorah diska; podkatalogi  hranyatsya kak obychnye diskovye
fajly,  poetomu oni mogut byt' raspolozheny v lyubom  meste  diska.
Otmetim, chto fiksirovannyj disk mozhet soderzhat' do chetyreh korne-
vyh  katalogov,  esli on razbit na razdely, hotya MS  DOS  "vidit"
tol'ko odin  kornevoj  katalog.  Katalogi  mogut  imet' razlichnye
razmery, v zavisimosti ot razmera diska i ego razbieniya na razde-
ly. V  sleduyushchej  tablice  privedeny  razmery  i pozicii kornevyh
katalogov dlya raznyh tipov diskov:

Tip diska    Razmer kataloga   CHislo elementov  Nachal'nyj sektor

disketa 160K     4 sektora           64                9
disketa 180K     4 sektora           64                9
disketa 320K     7 sektorov         112               15
disketa 360K     7 sektorov         112               15
disketa 1.2M    14 sektorov         224               29
zhestkij 10M         ----------peremennye------------
zhestkij 20M         ----------peremennye------------

V  zavisimosti  ot razbieniya na razdely fiksirovannyj disk  mozhet
imet' razlichnye razmery kataloga i nomer nachal'nogo sektora. Esli
ves' disk otveden dlya MS DOS, to na XT i AT pod kornevoj  katalog
otvoditsya 32 sektora, chto pozvolyaet imet' v nem 512 elementov.
   Kak kornevoj katalog, tak i  podkatalogi,  ispol'zuyut 32 bajta
dlya hraneniya informacii ob odnom fajle, nezavisimo ot tipa diska.
Takim obrazom v kazhdom sektore mozhet hranit'sya informaciya o 16-ti
elementah  kataloga.   Kazhdoe 32-bajtnoe pole  razbito  sleduyushchim
obrazom:

   bajty 0-7   Imya fajla
        8-10   Rasshirenie fajla
          11   Atribut fajla
       12-21   Zarezervirovano
       22-23   Vremya poslednego dostupa k fajlu
       24-25   Data poslednego dostupa k fajlu
       26-27   Nachal'nyj klaster
       28-31   Razmer fajla

Tochka mezhdu imenem fajla i ego 3-bajtnym rasshireniem ne hranitsya.
Vse  polya vyravneny na levuyu granicu, a pustye bajty  zapolnyayutsya
probelami (kod ASCII  32).  Atribut  fajla opredelyaet yavlyaetsya li
fajl spryatannym, zashchishchennym ot zapisi i t.d.  [5.2.6].  On opred-
lyaet takzhe special'nye elementy  kataloga,  takie kak podkatalogi
ili  metka toma.  Informaciya o vremeni i date upakovana,  poetomu
dlya chteniya etih znachenij trebuyutsya bitovye operacii [5.2.5].
   Nachal'nyj klaster ukazyvaet  na  poziciyu  v tablice razmeshcheniya
fajlov (FAT), kotoraya obsuzhdalas' v [5.1.1].  FAT hranit informa-
ciyu o svobodnom prostranstve  na  diske,  a takzhe otvodit sektora


pri  zapisi fajla.  FAT otvodit diskovoe  prostranstvo  porciyami,
bol'shimi chem 1 sektor, kotorye nazyvayutsya klasterami. Fajl raspo-
lozhen  v cepochke klasterov i FAT soderzhit sootvetstvuyushchuyu cepochku
elementov, ukazyvayushchih, gde eti  klastery  raspolozheny  na diske.

Katalog  dolzhen  ukazyvat' na nachal'noe zveno  cepochki  elementov
fajla v FAT, i eta informaciya  soderzhitsya  v pole nachal'nyj nomer
klastera. Poskol'ku fajl obychno zanimaet poslednij otvedennyj emu
klaster ne celikom,  to  pole  razmer  fajla  hranit tochnuyu dlinu
fajla v bajtah.




   Katalogi diska podrazdelyayutsya na kornevoj katalog (obsuzhdaemyj
zdes') i podkatalogi (obsuzhdaemye v [5.2.3]).  Kogda pol'zovatel'
programmy  vvodit  imya kakogo-libo fajla dlya  raboty,  to  byvaet
poleznym proverit', imeetsya li  etot  fajl na samom dele.  Obychno
izmeneniya  v kornevom kataloge proizvodyatsya v hode obychnyh fajlo-
vyh operacij ili s pomoshch'yu special'nyh  funkcij DOS. Odnako mozhno
rabotat'  s  katalogom napryamuyu.  Bol'shaya nuzhda v  takom  podhode
voznikaet pri rabote na yazykah  vysokogo  urovnya, gde utility DOS
po bol'shej chasti nedostupny.
   Kornevoj katalog chitaetsya i izmenyaetsya zagruzkoj ego v  pamyat'
s ispol'zovaniem podhoda,  pokazannogo  v [5.4.2], kogda chitayutsya
absolyutnye  sektora diska.  |ti operacii ne ostavlyayut mesta mezhdu
sektorami, kogda  oni  zagruzhayutsya  v  pamyat'.  Bufer, soderzhashchij
dannye sektora, mozhet rassmatrivat'sya kak nabor 32-bajtnyh  polej
i para ukazatelej, kotorye  mogut  ispol'zovat'sya dlya dvizheniya po
katalogu.   Odin ukazatel' vsegda kraten 32 i ukazyvaet na nachalo
elementa kataloga.  Vtoroj ukazatel' dobavlyaetsya k pervomu i uka-
zyvaet  na odno iz polej v 32-bajtnom elemente.  Dannye v  pamyati
mogut byt' izmeneny trebuemym obrazom, a zatem ves' bufer zapisy-
vaetsya obratno na disk.
   Imeetsya dva metoda chteniya absolyutnyh sektorov diska i v  oboih
sluchayah tol'ko odno chislo otlichaet  sluchai chteniya i zapisi.  Pos-
kol'ku oshibka pri zapisi na disk mozhet legko povredit' vse soder-
zhimoe diska, to nado  dejstvovat'  akkuratno.  Snachala ubedites',
chto  operaciya chteniya sektora vypolnena verno vo vseh  otnosheniyah.
Posle etogo mozhno poprobovat' zapisat' na disk, vzyav tochnuyu kopiyu
koda, ispol'zovannogo dlya chteniya i zameniv tol'ko nomer funkcii.

   Vysokij uroven'.

   Bejsik  vyvodit katalog po komande FILES.  Pri etom  vyvodyatsya
tol'ko imena fajlov. FILES daet  katalog nakopitelya po umolchaniyu;
dlya ukazaniya nakopitelya napishite FILES "A:" i t.d. Mozhno potrebo-
vat', chtoby byla vyvedena  informaciya ob otdel'nom fajle, napisav
FILES  "A:MYFILE.DAT".   Kak i v operacionnoj sisteme  imya  fajla
mozhet soderzhat' * i ?.  Operator FILES snabzhaet informaciej pol'-
zovatelya,  no  inogda  nalichie nekotorogo fajla  hochet  proverit'
programma.  V etom sluchae nado otkryt' fajl dlya posledovatel'nogo
chteniya  i esli on ne sushchestvuet, to vozniknet oshibochnaya situaciya.
Smotrite obsuzhdenie i primer v [5.2.3].


   Dlya poiska lyuboj informacii, otnosyashchejsya k kornevomu katalogu,
ispol'zujte  proceduru na mashinnom yazyke, privedennuyu v  [5.4.2].
Posle togo kak dannye kataloga  v  pamyati,  ustanovite ukazateli,
kak  opisano vyshe, i vedite poisk po buferu  pamyati s  32-bajtnym
intervalom. Nizheprivedennyj primer ishchet element kataloga, otnosya-
shchijsya  k  stertomu fajlu.  Kogda fajl stiraetsya, to  pervyj  bajt
imeni fajla zamenyaetsya na E5H, no vse ostal'noe soderzhimoe danno-
go elementa ostaetsya neizmennym.  Konechno, pri etom osvobozhdaetsya
diskovoe prostranstvo, otvedennoe fajlu v FAT.  Procedura vossta-
novleniya udalennogo fajla dolzhna znat' nomer nachal'nogo  klastera
v FAT. V  primere  etot  2-bajtnyj  nomer  klastera pomeshchaetsya so
smeshcheniem 26 v elemente kataloga.

100 '''chtenie sektorov kataloga v pamyat' s segmenta &H2000
110 INPUT "Enter erased filename ", FNAME$
120 IF LEN(FNAME$) > 12 THEN BEEP: GOTO 110
130 IF INSTR(FNAME$,".") > 9 THEN BEEP: GOTO 110
140 '''dopolnenie imeni i rasshireniya fajla nulyami
150 Y = INSTR(FNAME$,".")
160 IF Y = 0 THEN FIRSTPART$ = FNAME$: GOTO 230
170 EXTEN$ = LEFT$(FNAME$, LEN(FNAME$) - Y)
180 EXTEN$ = EXTEN$ + STRING$(3 - LEN(EXTEN$),"")
190 FIRSTPART$ = RIGHT$(FNAME$,Y - 1)
200 FIRSTPART$ = FIRSTPART$ + STRING$(8 - LEN(FIRSTPART$),"")
210 FNAME$ = FIRSTPART$ + EXTEN$
220 '''teper' hotim najti udalennyj fajl
230 MID$(FNAME$,1,1) = CHR$(&HE5)  'zamenyaem pervyj simvol
240 DIRPTR = 0                     'ukazatel' na element
250 FIELDPTR = 26                  'ukazatel' na nomer klastera
260 FOR N = 1 TO 112               'na diskete 112 elementov
270 X$ = ""                        'chistim X$
280 FOR M = 0 TO 10                'chitaem imya fajla iz kataloga
290 X$ = X$ + PEEK(DIRPTR + M)     'berem po simvolu
300 NEXT                           '
310 IF X$ = FNAME$ THEN 340        'sovpadaet s vvedennoj strokoj
320 NEXT                           'esli net, to sleduyushchij
330 PRINT "Too late - file entry obliterated": END  'uzhe net
340 X = PEEK(DIRPTR + FIELDPTR)    'nashli ego, berem 1-j bajt i
350 Y = PEEK(DIRPTR + FIELDPTR + 1)  '2-j bajt nomera klastera
360 Z = X + 256*Y                  'teper' nomer klastera v Z

   Srednij uroven'.

   MS  DOS obespechivaet dve pary funkcij dlya poiska fajlov,  odna
dlya fajlov, otkrytyh metodom upravlyayushchih blokov fajla, a drugaya -
dlya fajlov, otkrytyh metodom deskriptora fajlov.  Odna iz funkcij
kazhdoj pary ishchet pervoe poyavlenie  imeni fajla v kataloge, a dru-
gaya  ishchet posleduyushchie poyavleniya, kogda v imeni  fajla  soderzhatsya
dzhokery. Tol'ko  metod,  ispol'zuyushchij  deskriptor fajla pozvolyaet
iskat' podkatalogi.

Metod FCB:

   Funkciya 11H preryvaniya 21H ishchet pervoe poyavlenie fajla.  Usta-
novite DS:DX na neotkrytyj FCB i vypolnite  funkciyu. Pri vozvrate


AL  budet  soderzhat' 0, esli fajl najden, i FF - esli  net.   DTA
zapolnyaetsya informaciej iz kataloga.  Dlya obychnyh FCB pervyj bajt
DTA  soderzhit  nomer nakopitelya (1 = A i  t.d.), a  sleduyushchie  32
bajta soderzhat element  kataloga.   Dlya rasshirennogo FCB pervye 7
bajtov fajla kopiruyutsya v pervye 7 bajtov rasshirennogo FCB, vos'-
moj bajt ukazyvaet na  nakopitel', a sleduyushchie 32 bajta - element
kataloga.

;---v segmente dannyh
FCB     DB    1,'NEWDATABAK',25DUP(0)

;---ishchem fajl
   MOV  AH,11H    ;funkciya poiska v kataloge
   LEA  DX,FCB    ;ukazyvaem na FCB
   INT  21H       ;ishchem
   CMP  AL,0      ;uspeshno?
   JNE  NO_FILE   ;esli net, to procedura obrabotki oshibki
   LEA  BX,DTA    ;teper' DS:BX ukazyvaet na element kataloga

   Posle ispol'zovaniya funkcii 11H mozhno ispol'zovat' funkciyu 12H
dlya poiska sleduyushchih podhodyashchih elementov, kogda imya fajla soder-
zhit dzhokery. V dannom sluchae v imeni fajla dopustim tol'ko simvol
"?", no ne "*". |ta  funkciya  rabotaet  v  tochnosti tak zhe, kak i
pervaya, i esli najden vtoroj fajl, to informaciya o pervom fajle v
DTA budet unichtozhena povtornoj zapis'yu.

Metod deskriptora fajlov:

   Funkciya 4EH preryvaniya 21H  ishchet  fajl  s dannym imenem. DS:DX
dolzhny ukazyvat' na stroku, dayushchuyu put' fajla. Naprimer, B:\EURO-
PE\FRANCE\PARIS ukazyvaet na  fajl  PARIS. Stroka mozhet soderzhat'
do  63 simvolov i zavershat'sya simvolom ASCII 0.  Imya fajla  mozhet
soderzhat' dzhokery, vklyuchaya kak "?",  tak i "*". Pomestite atribut
fajla v CX; esli on obychnyj to 0, v protivnom sluchae  prokonsul'-
tirujtes' v [5.2.6] otnositel'no znachenij atributa.
   Pri vozvraet ustanavlivaetsya  flag perenosa, esli fajl ne naj-
den.   Esli fajl najden, to funkciya zapolnyaet DTA  informaciej  o
fajle. Otmetim chastnyj sluchaj  ispol'zovaniya DTA metodom deskrip-
tora fajlov - obychno, DTA ispol'zuetsya funkciyami MS DOS dlya rabo-
ty cherez FCB. Pervye 21 bajt  DTA  zarezervirovany DOS dlya poiska
sleduyushchih  sovpadayushchih fajlov.  Dvadcat' vtoroj bajt daet atribut
fajla, za nim sleduyut dva bajta, soderzhashchie vremya i eshche dva bajta
soderzhashchie datu. Sleduyushchie 4 bajta soderzhat razmer fajla (mladshee
slovo snachala).  I, nakonec, daetsya imya fajla v vide stroki pere-
mennoj  dliny, zakanchivayushchejsya bajtom ASCII 0.  Tochka (ASCII  46)
razdelyaet imya i rasshirenie i ne odin  iz etih elementov ne zapol-
nen probelami.

;---v segmente dannyh
PATH       DB     'B:FRANCE\PARIS\4EME',0


;---ishchem fajl
   MOV  AH,4EH        ;nomer funkcii
   LEA  DX,PATH       ;DS:DX ukazyvayut na put'
   MOV  CX,0          ;obychnyj atribut fajla
   INT  21H           ;ishchem fajl
   JC   NO_FILE       ;uhod, esli ne najden
   LEA  BX,DTA        ;DS:BX ukazyvayut na DTA
   MOV  AL,[BX]+21    ;teper' atribut fajla v AL

   Sleduyushchee  poyavlenie imeni fajla (kogda ispol'zuyutsya  dzhokery)
ishchetsya s pomoshch'yu funkcii  4FH  preryvaniya  21H.  Ona  gotovitsya v
tochnosti  tak  zhe, kak i funkciya 4EH, pri etom ukazatel'  DTA  ne
dolzhen menyat'sya.  Kogda drugih sovpadenij ne najdeno, to ustanav-
livaetsya flag perenosa, a v AX poyavlyaetsya 18.




   Programma mozhet sozdavat' ili  udalyat' podkatalogi, pri vypol-
nenii  nekotoryh uslovij.  Dlya sozdaniya  podkataloga  neobhodimo,
chtoby bylo po krajnej mere odno pustoe mesto v kornevom kataloge.
Dlya  udaleniya podkataloga neobhodimo, chtoby on ne soderzhal fajlov
ili ssylok na drugie  podkatalogi.  Krome togo, Vy ne mozhete uda-
lit' podkatalog, kotoryj yavlyaetsya Vashim tekushchim katalogom (tot, s
kotorym po  umolchaniyu  vypolnyayutsya  vse operacii nad katalogami).
Otmetim takzhe, chto nevozmozhno udalit' kornevoj katalog.

   Vysokij uroven'.

   Bejsik  predostavlyaet  komandy MKDIR (sozdaj katalog) i  RMDIR
(udali katalog).  Za  obeimi  dolzhny  sledovat'  standartnye puti
ukazaniya kataloga, soderzhashchie do 63 simvolov, vklyuchaya imya nakopi-
telya.  Put' dolzhen byt' zaklyuchen v kavychki. CHtoby dobavit' podka-
talog  s imenem STORKS v podkatalog BIRDS napishite MKDIR  "B:MAM-
MALS\BIRDS\STORKS".  Posle  vypolneniya  etoj komandy budet sozdan
fajl STORKS, ispol'zuemyj kak podkatalog i fakt ego sushchestvovaniya
budet otrazhen v sozdanii elementa s imenem STORKS v podkataloge s
imenem BIRDS. Dlya udaleniya etogo podkataloga nado snachala udalit'
iz nego vse fajly [5.3.2]. Zatem  nado ispol'zovat' komandu RMDIR
"B:MAMMALS\BIRDS\STORKS".
   V  etih  primerah predpolagalos', chto Vashim tekushchim  katalogom
yavlyalsya kornevoj katalog.  Odnako, esli Vash tekushchij katalog naho-
ditsya  gde-to  na puti k podkatalogu, nad kotorym  osushchestvlyayutsya
operacii, to net neobhodimosti ukazyvat' ves' put'. Poetomu, esli
Vashim tekushchim katalogom yavlyaetsya BIRDS, to dlya sozdaniya ili  uda-
leniya  podkataloga  STORKS   mozhno   ispol'zovat'  komandy  MKDIR
"\STORKS" ili RMDIR "\STORKS".

   Srednij uroven'.

   Poskol'ku upravlyayushchie bloki fajlov obsluzhivayut tol'ko kornevoj
katalog, to dlya sozdaniya ili  udaleniya podkataloga nado ispol'zo-
vat' deskriptory fajlov.


Sozdanie podkataloga:
   DS:DX  dolzhny ukazyvat' na stroku, dayushchuyu nakopitel' i put'  k
katalogu, v kotorom dolzhen byt' sozdan podkatalog.  Stroka dolzhna
zavershat'sya  bajtom  ASCII 0.  Dlya otkrytiya podkataloga s  imenem
PRIMATES v kornevom kataloge nakopitelya A: nado zapisat' stroku v
vide "A:\PRIMATES". Dlya otkrytiya podkataloga v drugom podkataloge
s imenem MAMMALS napishite "A:\MAMMALS\PRIMATES".  Imya  nakopitelya
A: mozhet byt' opushcheno esli Vy rabotaete s nakopitelem, ispol'zue-
mym  po  umolchaniyu, i put' mozhet nachinat'sya s tekushchego  kataloga.
Pomestite v AH 39H i vypolnite  preryvanie  21H; esli ukazan pra-
vil'nyj put', to budet sozdan novyj katalog.  V protivnom  sluchae
budet ustanovlen flag perenosa, a AX budet soderzhat' kod oshibki 3
(put' neveren) ili 5 (net dostupa).  V primere sozdaetsya podkata-
log PRIMATES:

;---v segmente dannyh
PATH    DB   'A:MAMMALS\PRIMATES',0

;---sozdaem podkatalog s imenem PRIMATES
   LEA  DX,PATH     ;DS:DX dolzhny ukazyvat' na put'
   MOV  AH,39H      ;nomer funkcii
   INT  21H         ;sozdaem podkatalog
   JC   ERROR_ROUT  ;obrabotka oshibok

Udalenie podkataloga:
   Dlya udaleniya podkataloga nado sformirovat' stroku, v tochnost'yu
sovpadayushchuyu  s toj, kotoruyu Vy ukazyvali pri  sozdanii  kataloga.
Zatem pomestite v AH 3AH i  vypolnite  preryvanie 21H.  Opyat' pri
nevypolnenii  funkcii  v AX budut vozvrashcheny kody 3 ili 5 (kod  5
mozhet ukazyvat', chto katalog nepustoj).




   Podkatalogi vo mnogom podobny kornevomu  katalogu, za isklyuche-
niem  togo,  chto oni hranyatsya kak obychnye fajly, a  ne v  zaranee
predopredelennyh sektorah. Podkatalogi nevozmozhno sputat' s obych-
nymi fajlami, poskol'ku ob®ekt kataloga, otnosyashchijsya k podkatalo-
gu, imeet special'nyj bajt  atributov  (s ustanovlennym bitom 5 -
sm.  [5.2.6]). Podkatalogi nachinayutsya s dvuh special'nyh 32-bajt-
nyh ob®ektov, pervyj iz kotoryh  imeet  imya tochka, a vtoroj - dve
tochki.   Oni orientiruyut podkatalog sredi  okruzhayushchih  katalogov.
Ssylki na podkatalogi  nizhnego  urovnya  zapisyvayutsya  kak obychnye
ssylki na fajly.
   Predpolagaetsya,  chto podkatalog mozhet byt' prochitan kak  lyuboj
drugoj fajl, poetomu vrode by ne sostavlyaet truda zagruzit' ego v
pamyat'.   No,  k sozhaleniyu, sozdateli MS DOS pomestili  0 v  pole
dliny fajla dlya elementov, otnosyashchihsya k podkatalogam.  V rezul'-
tate DOS schitaet, chto etot fajl imeet nulevuyu dlinu i otkazyvaet-
sya chitat' ego. Net prostogo sposoba preodolet' etu problemu.

   Vysokij uroven'.

   V Bejsike komanda FILES mozhet  ispol'zovat'  standartnye imena
putej  dlya vyvoda podkataloga; naprimer, FILES  "B:MAMMALS\BIRDS"


vyvodit vse fajly, soderzhashchiesya v podkataloge BIRDS.  |ta komanda
mozhet  byt' ispol'zovana i dlya polucheniya informacii o  nalichii  v
kataloge opredelennogo  fajla.  Naprimer,  FILES "LEVEL1\NEWDATA"
ishchet  fajl NEWDATA i vyvodit ego imya, esli on najden.   Hotya  eto
mozhet byt' poleznym  dlya  pol'zovatelya,  no chasto samoj programme
neobhodimo znat' sushchestvuet ili net ukazannyj fajl. CHtoby ustano-
vit' eto popytajtes' otkryt'  fajl  dlya posledovatel'nogo chteniya.
Esli on ne budet najden, to vozniknet oshibochnoe uslovie 63.  Soz-
dajte proceduru obrabotki  oshibok,  kak opisano v [5.4.8].  Zatem
ispol'zujte  peremennuyu,  chtoby otmetit' byl li najden  trebuemyj
fajl (v nashem  primere  peremennaya  "EXISTS").  Esli programme ne
nuzhno,  chto  etot fajl byl otkryt, to zakrojte ego pered tem  kak
dvinut'sya dal'she.

100 ON ERROR GOTO 1000      'procedura obrabotki oshibok
110 EXISTS = 1              'nachal'noe znachenie "flaga"
120 INPUT "Enter filename: ",S$  'zapros imeni fajla
130 OPEN S$ FOR INPUT AS #3 'otkryvaem ego dlya posled. chteniya
140 IF EXISTS = 0 THEN BEEP: PRINT "File does not exist"
 .
 .
1000 IF ERR = 53 THEN 1500  'fajl ne sushchestvuet?
1010 IF ERR = 64 THEN ...   'drugie oshibki
 .
1500 EXISTS = 0             'menyaem znachenie flaga
1510 RESUME 140             'prodolzhaem vypolnenie programmy

   Srednij uroven'.

   Funkcii raboty cherez  deskriptory  fajlov, kotorye ispol'zova-
lis' dlya dostupa k kornevomu katalogu [5.2.1] mogut tak zhe prosto
obrashchat'sya k lyubomu  podkatalogu.   CHtoby  vyvesti vse soderzhimoe
kataloga  nado prosto ispol'zovat' funkciyu 4EH dlya poiska  fajlov
*.*, a zatem povtoryat' poisk, ispol'zuya funkciyu 4FH. Kogda bol'she
ne  budet fajlov, to budet ustanovlen flag perenosa, a  AL  budet

soderzhat'  18.  Kazhdyj raz, kogda budet obnaruzhen ocherednoj  ele-
ment, v DTA budet zapisana informaciya o fajle, vklyuchaya polnyj ego
put'  (otmechaem ispol'zovanie DTA v funkciyah, ispol'zuyushchih  desk-
riptor fajla).  Sleduyushchij primer vyvodit polnye puti vseh obychnyh
fajlov podkataloga.

;---v segmente dannyh
PATH     DB   'A:MAMMALS\*.*',0
DTAH     DB   256 DUP(?)

;---ustanovka DTA
            LEA  DX,DTA        ;DS:DX ukazyvayut na DTA
            MOV  AH,1AH        ;funkciya ustanovki DTA
            INT  21H           ;ustanavlivaem DTA


;---ishchem pervyj fajl
            MOV  AH,4EH        ;nomer funkcii
            LEA  DX,PATH       ;ukazyvaem na stroku puti
            MOV  CX,0          ;tol'ko normal'nye atributy
            INT  21H           ;ishchem *.*
            JC   ERROR         ;obrabotka oshibok
;---vyvodim imya fajla
NEXT_LINE:  LEA  BX,DTA        ;BX ukazyvaet na DTA
            ADD  BX,30         ;smeshchenie dlya imeni fajla
NEXT_CHAR:  MOV  DL,[BX]       ;poluchaem simvol iz imeni
            CMP  DL,0          ;proverka na konec stroki
            JE   END_STR       ;uhod, esli konec
            MOV  AH,2          ;inache, vyodim simvol
            INT  21H           ;
            INC  BX            ;uvelichivaem ukazatel'
            JMP  SHORT NEXT_CHAR  ;sleduyushchij simvol
;---vozvrat karetki/perevod stroki v konce stroki
END_STR:    MOV  AH,2          ;funkciya vyvoda simvola
            MOV  DL,13         ;kod vozvrata karetki
            INT  21H           ;vyvodim
            MOV  DL,10         ;kod perevoda stroki
            INT  21H           ;vyvodim
;---ishchem sleduyushchij fajl
            LEA  DX,PATH       ;ukazyvaem na stroku puti
            MOV  AH,4FH        ;nomer funkcii
            INT  21H           ;ishchem sleduyushchij fajl
            JC   FINISHED      ;esli net, to vyhod
            JMP  SHORT NEXT_LINE  ;inache vyvodim imya fajla
FINISHED:




   Tekushchij  katalog  eto  katalog, v kotorom DOS ishchet  fajl,  dlya
kotorogo ne ukazan put'. Esli ne ustanovleno protivnogo, to teku-
shchij katalog yavlyaetsya kornevym katalogom.

   Vysokij uroven'.

   Bejsik ustanavlivaet tekushchij katalog s pomoshch'yu komandy  CHDIR.
Za komandoj dolzhna sledovat' stroka, ukazyvayushchaya put' k katalogu,
na kotoryj nado perejti. Stroka mozhet soderzhat' do 63-h simvolov,
vklyuchaya imya nakopitelya, i dolzhna byt' zaklyuchena v kavychki.  CHDIR
"C:MAMMALS\PRIMATES\GIBBONS"  delaet  podktalog  GIBBONS  tekushchim
katalogom.  CHtoby perejti v  kornevoj  katalog napishite CHDIR "\"
ili CHDIR "B:\".
   Bejsik versii 3.0 mozhet soobshchat' put' k tekushchemu katalogu, kak
eto  delaet  komanda  DOS   PATH.   Prosto  vvedite  PRINT  ENVI-
RON$("PATH").


   Srednij uroven'.

   Funkciya  3BH  preryvaniya 21H  ustanavlivaet  tekushchij  katalog.
DS:DX dolzhny ukazyvat' na  put'  k  katalogu v standartnom vide i
eta stroka dolzhna zavershat'sya bajtom ASCII 0. Naprimer, B:BIRDS\-
PARROTS\POLLY delaet POLLY tekushchim katalogom.  B: mozhet byt' opu-
shcheno,  esli  eto tekushchij nakopitel' po umolchaniyu [5.3.1].   CHtoby
sdelat' tekushchim kornevoj  katalog  nakopitelya  A: napishite A:\. V
primere tekushchim katalogom ustanavlivaetsya POLLY:

;---v segmente dannyh
PATH     DB   'B:BIRDS\PARROTS\POLLY',0

;---delaem POLLY tekushchim katalogom
   MOV  AH,3BH        ;nomer funkcii
   LEA  DX,PATH       ;DS:DX dolzhny ukazyvat' na put'
   INT  21H           ;ustanavlivaem tekushchij katalog

   CHtoby opredelit' kakoj katalog yavlyaetsya tekushchim nado ispol'zo-
vat' funkciyu 47H preryvaniya  21H.  DS:SI  dolzhny ukazyvat' na ob-
last'  dannyh razmerom 64 bajta, v kotoruyu budet zapisan put'.  V
DL ukazyvaetsya nakopitel', prichem  0 = "po umolchaniyu", 1 = A, 2 =
B i t.d. Pri vozvrate funkciya vozvrashchaet stroku bez imeni nakopi-
telya.  Esli byl ukazan nesushchestvuyushchij nakopitel', to v AL vozvra-
shchaetsya kod oshibki 15.  Stroka nachinaetsya s imeni pervogo podkata-
loga cepochki, a ne s obratnoj kosoj  cherty. Bajt ASCII 0 signali-
ziruet  o  konce stroki.  V dannom primere imya tekushchego  kataloga
prisvaivaetsya peremennoj "CURRENT_DIR":

;---v segmente dannyh
CURRENT_DIR   DB   64 DUP(?)

;---poluchit' tekushchij katalog
   MOV  AH,47H         ;nomer funkcii
   LEA  SI,CURRENT_DIR ;ukazyvaem na oblast' dannyh
   MOV  DL,1           ;nakopitel' A
   INT  21H            ;pomeshchaet stroku po adresu DS:SI




   Esli otschityvat' ot nulya, to bajty 22-23 32-bajtnogo  elementa
kataloga soderzhat vremya poslednego dostupa k fajlu. Bajty 24-25 -
soderzhat datu. Znachenie bitov sleduyushchee:

Vremya:  bity 11-15    chasy (0-23)
              5-10    minuty (0-59)
               0-4    sekundy (0-29 s 2-sekundnym intervalom)

Data:   bity  9-15    god (0-119, smeshchenie s 1980 goda)
               5-8    mesyac (1-12)
               0-4    chislo (1-31)


Den'  nedeli ne zapisyvaetsya; DOS vychislyaet ego po ostal'noj  in-
formacii.  Otmetim  takzhe,  chto  kak  vsegda,  mladshij  bajt etih
2-bajtnyh znachenij raspolozhen ran'she v pamyati, chem starshij.

   Srednij uroven'.

   Metod  dostupa  k  fajlu s ispol'zovaniem  upravlyayushchego  bloka
fajla pozvolyaet poluchit' datu  poslednego  dostupa k fajlu, no ne
vremya.   Kogda  FCB otkryvaetsya funkciej 0FH preryvaniya  21H,  to
zapolnyaetsya dvuhbajtnoe pole daty  v vysheprivedennom formate. |to
pole raspolozheno v FCB so smeshcheniem 14H [5.3.5].
   S  drugoj storony, dostup k fajlu s pomoshch'yu deskriptora  fajla
pozvolyaet kak poluchit', tak i ustanovit'  datu i vremya poslednego
dostupa k fajlu.  Funkciya 57H preryvaniya 21H vypolnyaet vse opera-
cii. Dlya ustanovki vremeni i daty pomestite nomer fajla v BX, i 0
v AL. Dlya polucheniya daty i vremeni nado pomestit' v AL 1. V oboih
sluchayah data soderzhitsya v DX, a vremya v CX. Znachenie bitov sovpa-
daet s tem, chto opisano v tablice.  V tehnicheskom rukovodstve  po
MS DOS utverzhdaetsya, chto mladshie  bajty informacii nahodyatsya v CH
i  DH, i naoborot.  Na samom dele eto ne tak.  Pri  vozniknovenii
oshibki ustanavlivaetsya flag perenosa, a v AX vozvrashchaetsya 1, esli
v  AL ukazano nepravil'noe chislo i 6, esli plohoj deskriptor faj-
la. V sleduyushchem primere opredelyaetsya chas, v kotoryj byl poslednij
lostup k fajlu:

;---v segmente dannyh
PATH   DB   'B:NEWDATA.BAK',0
;---otkryvaem fajl
   LEA  DX,PATH         ;ukazyvaem na stroku puti
   MOV  AH,3DH          ;funkciya otkrytiya fajla
   MOV  AL,0            ;otkryvaem dlya chteniya
   INT  21H             ;otkryvaem fajl
   JC   OPEN_ERROR      ;perehod na obrabotku oshibki
;---poluchaem datu i vremya dostupa k fajlu
   MOV  BX,AX           ;pomeshchaem nomer fajla v BX
   MOV  AL,0            ;kod dlya chteniya vremeni
   MOV  AH,57H          ;nomer funkcii
   INT  21H             ;poluchaem vremya dostupa
   JC   TIME_ERROR      ;perehod na obrabotku oshibok
;---sdvigaem bity, otnosyashchiesya k chasam, v nachalo CH
   MOV  CL,3            ;gotovim sdvig
   SHR  CH,CL           ;teper' CH soderzhit chas dostupa




   DOS  ispol'zuet shest' razlichnyh atributov fajlov, kotorye dayut
dannomu fajlu opredelennyj status.  Fajl mozhet imet' neskol'ko iz
etih atributov odnovremenno (no ne vse). Atributy ustanavlivayutsya
12-m bajtom 32-bajtnogo  elementa  kataloga.  Mladshie shest' bitov
imeyut znachenie, a ostal'nye dolzhny byt' ravny nulyu. Bity takie:


   esli bit 5 = 1,   to fajl byl izmenen so vremeni poslednej
                     arhivacii
            4 = 1,   to fajl yavlyaetsya podkatalogom
            3 = 1,   to etot element yavlyaetsya ne fajlom, a metkoj
                     toma
            2 = 1,   to fajl yavlyaetsya "sistemnym"
            1 = 1,   to fajl spryatan pri poiske po katalogu
            0 = 1,   to fajl ob®yavlen tol'ko dlya chteniya

Bit 5 eto arhivnyj bit, ispol'zuemyj programmami BACKUP i RESTORE
DOS. |tot bit s'rasyvaetsya v 0 posle arhivacii i ustanavlivaetsya,
kogda s fajlom snova rabotali. Pri sleduyushchej arhivacii neizmenen-
nye fajly mogut byt' obnaruzheny i proignorirovany.

   Vysokij uroven'.

   Bejsik ne pozvolyaet Vam  ustanavlivat'  atributy  fajla pryamo.
Sprav'tes' v [5.2.1], kak schitat' katalog v pamyat', najti  nuzhnyj
fajl, sdelat' izmeneniya i snova zapisat' ego na disk.  Kak tol'ko
katalog pomeshchaetsya v pamyat', bajty  atributov nahodyatsya po smeshche-
niyam 11, 43, 75 i t.d. Esli nuzhno, to Vy mozhete prochitat' tekushchie
atributy i izmenit' tol'ko odin  bit,  ispol'zuya  tehniku bitovyh
operacij,  opisannuyu v prilozhenii B.  No legche prosto  perepisat'
vse atributy zanovo.  Bud'te  vnimatel'ny,  oshibki mogut byt' fa-
tal'nymi.   V dannom primere schityvayutsya atributy fajla s  imenem
"NEWDATA.AAA".

100 'chitaem sektora kataloga, nachinaya s &H2000 i zatem ...
110 DEF SEG = &H2000         'ukazyvaem na oblast' kataloga
120 FILENAME$ = "NEWDATAAAA" 'ishchem imya fajla bez tochki
130 DIRPTR = 0               'ukazatel' v kataloge
140 FOR N = 1 TO 112         'proveryaem vse elementy
150 X$ = ""                  'vremennaya stroka dlya imeni fajla
160 FOR M = 0 TO 10          'dlya kazhdogo simvola imeni
170 X$ = X$+PEEK(DIRPTR+M)   'dobavlyaem ego k stroke
180 NEXT                     '
190 IF X$ = FILENAME$ THEN 220  'esli imya najdeno, to uhodim
200 NEXT                     '
210 PRINT "File not found": END  'net takogo fajla
220 X = PEEK(DIRPTR+11)      'poluchaem atributy nuzhnogo fajla
230 IF X AND 32 <> 0 THEN PRINT "File not baked up"
240 IF X AND 16 <> 0 THEN PRINT "File is a subdirectory"
250 IF X AND 8 <> 0 THEN PRINT "Volume label - not a file"
260 IF X AND 4 <> 0 THEN PRINT "File is a system file"
270 IF X AND 2 <> 0 THEN PRINT "File is a hidden file"
280 IF X AND 1 <> 0 THEN PRINT "File is read-only"

   Srednij uroven'.

   Funkciya 43H preryvaniya 21H mozhet  kak nahodit', tak i izmenyat'
atributy  fajla, no tol'ko esli fajl byl otkryt s pomoshch'yu  metoda
deskriptora fajlov, a ne  s  pomoshch'yu  metoda  upravlyayushchego  bloka


fajla. Net analogichnoj funkcii dlya FCB. Bajt atributov mozhet byt'
ustanovlen pri sozdanii  fajla   [5.3.2],  ispol'zuya  rasshirennyj
upravlyayushchij blok fajla.  No esli Vy posledovatel'no otkroete FCB,
izmenite ustanovku atributov  i  zatem  zakroete  fajl, to u nego
ostanutsya pervonachal'nye atributy. Hotya, konechno, Vy mozhete izme-
nit' atributy kakim-nibud'  obhodnym  putem, no namnogo proshche is-
pol'zovat' funkciyu, ispol'zuyushchuyu metod deskriptora fajlov.
   CHtoby ispol'zovat' funkciyu 43H, pomestite 1 v AL, chtoby  pris-
voit' fajlu bajt  atributov,  soderzhashchijsya  v CX (na samom dele v
CL, poskol'ku CH raven 0). Mozhno naoborot pomestit' v AL 0, chtoby
v CX byl vozvrashchen tekushchij bajt atributov fajla.  V oboih sluchayah
DS:DX  dolzhny  ukazyvat' na stroku, dayushchuyu put' k  fajlu.   Konec
stroki otmechaetsya bajtom ASCII 0  (kotoryj ne vhodit v chislo 63-h
simvolov).  V primere status "hidden" (spryatannyj)  prisvaivaetsya
fajlu OVERDUE:

;---v segmente dannyh
PATH   DB   'A:ACCOUNTS',0

;---vklyuchaem priznak spryatannogo fajla
   MOV  AH,43H          ;nomer funkcii
   MOV  AL,0            ;chitaem bajt atributov
   LEA  DX,PATH         ;DS:DX ukazyvayut na put'
   INT  21H             ;bajt atributov v CX
   JC   ERROR_ROUTINE   ;obrabotka oshibok
   OR   CL,10B          ;vklyuchaem bit 1
   MOV  AH,43H          ;nomer funkcii
   MOV  AL,1            ;zamenyaem bajt atributov
   INT  21H             ;teper' fajl stal spryatannym

Flag perenosa ustanavlivaetsya  pri  vozniknovenii oshibki.  V etom
sluchae  v  AX vozvrashchaetsya 2 - esli fajl ne najden, 3 -  esli  ne
najden put' i 5 - pri drugih oshibkah (net dostupa).




   Metka toma dlya diskety -  eto  element  kataloga, imeyushchij spe-
cial'nyj atribut. Metka zanimaet pervye 11 bajtov elementa, otno-
syashchiesya k imeni i rasshireniyu fajla. Bajt atributov po smeshcheniyu 11
soderzhit znachenie 8 (bit 3 = 1).  Polya vremeni i daty zapolnyayutsya
obychnym obrazom. Odnim iz svojstv etogo atributa yavlyaetsya to, chto
dannyj element ne vyvoditsya po komande DIR.
   Metka  mozhet  zanimat' lyubuyu poziciyu v kataloge.   Ona  ishchetsya
pereborom vseh bajtov  atributov,  poka ne budet najdeno znachenie
8.   CHtoby  steret' metku nado prosto pomestit' E5 v pervyj  bajt
sootvetstvuyushchego elementa - sam  bajt  atributov mozhno ne menyat'.
CHtoby  izmenit'  metku nado zapisat' novye 11  simvolov  (ostatok
nado  zapolnit'  probelami).  CHtoby  prisvoit'  metku toma disku,
kotoryj ne imel ee, nado najti pustoe mesto v kataloge i zapisat'
tuda metku i sootvetstvuyushchij atribut, nichego bol'she ne trebuetsya.


   Vysokij uroven'.

   Obsuzhdenie v [5.4.2] ob®yasnyaet  kak chitat' i pisat' absolyutnye
sektora  v Bejsike.  Dlya standartnoj dvuhstoronnej  diskety  nado
ispol'zovat' nomer storony 0,  nomer dorozhki 0, nomer sektora - 6
i  chislo sektorov dlya chteniya/zapisi - 7.  Posle togo, kak  dannye
zapisany v otvedennyj  bufer,  primery,  privedennye  zdes' mogut
byt' ispol'zovany dlya izmeneniya ili dobavleniya metki toma.  Zatem
sektora dolzhny  byt'  perezapisany  na  disk. Bud'te vnimatel'ny:
oshibka mozhet privesti k potere vsej informacii na diske.   Dannyj
primer ishchet metku toma i izmenyaet ee:

100 'sektora zagruzheny, nachinaya skazhem s &H1000
110 DEF SEG = &H1000
120 DIRPTR = 11           'ukazatel' na bajt atributov
130 FOR N = 1 TO 112      'proveryaem vse elementy kataloga
140 IF PEEK(DIRPTR) = 8 THEN 180  'uhod esli metka toma
150 DIRPTR = DIRPTR + 32  'ukazyvaem na sled. element
160 NEXT                  'proveryaem ego atribut
170 PRINT "No volume label found": END  'metki net
180 INPUT "Enter new volume label", V$  'zapros metki
190 IF LEN(V$) > 11 THEN BEEP: PRINT "11 chars only": GOTO 180
200 V$ = V$ + STRING$(11-LEN(V$),32)  'dopolnyaem probelami
210 DIRPTR = DIRPTR - 11  'vozvrashchaemsya na nachalo elementa
220 FOR N = 1 TO LEN(V$)  'pomeshchaem vse simvoly metki
230 POKE N,MID$(V$,N,1)   'v pamyat'
240 NEXT                  '
250 'teper' ostalos' perezapisat' sektora na disk

   Nizkij uroven'.

   V nizheprivedennom primere predpolagaetsya, chto Vy sozdali bufer
dannyh  razmerom 3584 bajt, dlya hraneniya vseh semi sektorov kata-
loga diskety emkost'yu 360K.  Bufer nazyvaetsya DIR_AREA.  V pervom
primere metka toma ishchetsya i vyvoditsya, ili, esli ona ne  najdena,
to vyvoditsya soobshchenie ob ee  otsutstvii.   Dlya  udobstva oblast'
bufera  dlya sektorov otvoditsya v segmente dannyh;  luchshe  otvesti
pamyat' dlya zadachi, a zatem osvobodit' ee [1.3.1].

;---v segmente dannyh
VOL_STRING   DB    'The volume label is $'
NO_LABEL     DB    'There is no volume label $'
DIR_AREA     DB    3584 DUP(?)

;---chitaem 7 sektorov kataloga
         MOV  AX,SEG DIR_AREA         ;segment bufera
         MOV  ES,AX                   ;
         MOV  BX,OFFSET DIR_AREA      ;smeshchenie bufera
         MOV  DL,0                    ;nomer nakopitelya
         MOV  DH,0                    ;nomer golovki
         MOV  CH,0                    ;nomer dorozhki
         MOV  CL,6                    ;startovyj sektor


         MOV  AL,7                    ;chislo sektorov kataloga
         MOV  AH,2                    ;nomer funkcii chteniya
         INT  13H                     ;chitaem katalog v pamyat'
;---ishchem metku toma, sravnivaya bajt atributov s 8
         MOV  CX,112                  ;chislo elementov
         ADD  BX,11                   ;smeshchenie dlya atributov
TRY_AGAIN:   MOV  AL,[BX]             ;berem 1-j element
         CMP  AL,8                    ;eto metka toma?
         JE   GOT_IT                  ;esli da, to uhod
         ADD  BX,32                   ;inache na sled. element
         LOOP TRY_AGAIN               ;
;---vyvodim soobshchenie ob otsutstvii metki toma
         MOV  AH,9                    ;funkciya vyvoda stroki
         LEA  DX,NO_LABEL             ;ukazyvaem na stroku
         INT  21H                     ;vyvodim ee
         JMP  SHORT CONTINUE          ;na konec
;---vyvodim stroku, dayushchuyu metku toma
GOT_IT:  MOV  AH,9                    ;funkciya vyvoda stroki
         LEA  DX,VOL_STRING           ;ukazyvaem na stroku
         INT  21H                     ;vyvodim ee
         SUB  BX,11                   ;ukazatel' na metku
         MOV  CX,11                   ;pishem 11 simvolov
         MOV  AH,2                    ;funkciya vyvoda simvolov
NEXT_CHAR:   MOV  DL,[BX]             ;simvol v DL
         INT  21H                     ;vyvodim simvol
         INC  BX                      ;perehodim k sleduyushchemu
         LOOP NEXT_CHAR               ;
CONTINUE:

CHtoby steret' metku pomestite sleduyushchij kod v GOT_IT:

GOT_IT:   MOV  AL,0E5H     ;kod otmetki pustogo elementa
          SUB  BX,11       ;ukazatel' na nachalo elementa
          MOV  [BX],AL     ;menyaem pervyj bajt

CHtoby izmenit'  metku  toma,  nado  vmesto  etogo  ispol'zovat' v
GOT_IT sleduyushchij kod.  Predpolagaetsya, chto Vy podgotovili  gde-to
11-bajtnuyu stroku NEW_LABEL.

GOT_IT:   LEA  SI,NEW_LABEL  ;SI dolzhen ukazyvat' na stroku
          SUB  BX,11         ;BX ukazyvaet na nachalo metki
          MOV  DI,BX         ;pomeshchaem ukazatel' v DI
          MOV  CX,11         ;peresylka 11 simvolov
REP       MOVSB              ;peresylaem stroku

   CHtoby sozdat' metku  mozhno  ispol'zovat'  tot zhe samyj kod, no
nado  takzhe ustanovit' bajt atributov ravnyj 8 (Vy mozhete  prosto
dobavit' ASCII 8 k stroke,  soderzhashchej  novuyu metku, tak kak bajt
atributov neposredstvenno sleduet za samoj metkoj).
   I,  nakonec,  vo vseh sluchayah izmeneniya  kataloga,  neobhodimo
zapisat' katalog obratno na disk. Oshibki pri etom neprostitel'ny.


;---zapis' izmenennyh sektorov nazad na disk
   MOV  AX,SEG DIR_AREA        ;registry kak i pri chtenii
   MOV  ES,AX                  ;
   MOV  BX,OFFSET DIR_AREA     ;
   MOV  DL,0                   ;
   MOV  DH,0                   ;
   MOV  CH,0                   ;
   MOV  CL,6                   ;
   MOV  AL,7                   ;
   MOV  AH,3                   ;nomer funkcii zapisi sektorov
   INT  13H                    ;




   Programmy,  napisannye na yazykah vysokogo urovnya mogut  prosto
otkryt' fajl i vsya podgotovitel'naya rabota dlya operacij s fajlami
budet vypolnena avtomaticheski.  Odnako programmisty na yazyke  as-
semblera dolzhny sozdat'  special'nye  oblasti dannyh, kotorye is-
pol'zuyutsya  pri  operaciyah vvoda/vyvoda.  MS DOS  ispol'zuet  dva
metoda dostupa k fajlam, metod  upravlyayushchego  bloka fajla (FCB) i
metod deskriptora fajla. Metod FCB sohranilsya s teh por, kogda MS
DOS ne rabotala s drevovidnoj strukturoj katalogov, poetomu s ego
pomoshch'yu  mozhno  poluchit' dostup tol'ko k  fajlam,  nahodyashchimsya  v
tekushchem  kataloge.  Metod  deskriptora  fajla  pozvolyaet poluchit'
dostup k lyubomu fajlu, nezavisimo ot togo, kakoj katalog yavlyaetsya
tekushchim.
   Poskol'ku teper'  drevovidnaya  struktura  katalogov shiroko is-
pol'zuetsya,  to metod FCB stanovitsya anahronizmom, odnako MS  DOS
prodolzhaet podderzhivat' etot metod, chtoby sohranit' sovmestimost'
so  starym programmnym obespecheniem i po etoj prichine my rassmot-
rim i ego.  Odnako v  svoih  programmah  vsegda ispol'zujte metod
deskriptora fajla.  Metod deskriptora fajla imeet  dopolnitel'noe
preimushchestvo v tom, chto on  trebuet men'she podgotovitel'noj rabo-
ty. Odnako v nekotoryh prilozheniyah sami operacii vvoda/vyvoda pri
ego ispol'zovanii  mogut  okazat'sya  bolee slozhnymi, chem v metode
FCB.  Naprimer, operacii chteniya fajla s pryamym dostupom s ispol'-
zovaniem metoda deskriptora fajla  trebuyut chtoby programma vychis-
lyala smeshchenie kazhdoj zapisi v fajle, v to vremya kak sootvetstvuyu-
shchaya funkciya FCB poluchaet nomer zapisi i delaet neobhodimye vychis-
leniya sama.
   Prezhde  chem chitat' ili pisat' dannye fajl dolzhen byt'  otkryt.
Otkryt' fajl eto znachit sozdat'  i  inicializirovat'  special'nuyu
oblast'  dannyh,  ispol'zuemuyu MS DOS,  kotoraya  soderzhit  vazhnuyu
informaciyu o fajle, takuyu kak  imya  fajla, imya nakopitelya, razmer
zapisi  fajla  i t.d.  YAzyki vysokogo urovnya, takie kapk  Bejsik,
sozdayut eti oblasti  avtomaticheski.  Odnoj  iz takih oblastej yav-
lyaetsya upravlyayushchij blok fajla i kogda ispol'zuetsya metod FCB,  to
programma sozdaet etot blok, a  MS  DOS chitaet i manipuliruet ego
soderzhimym.   Pervonachal'no  FCB soderzhit tol'ko imya fajla i  imya
nakopitelya; posle togo kak fajl  otkryvaetsya  v  nego dobavlyaetsya
informaciya o razmere zapisi fajla i o tekushchej pozicii, s  kotoroj
k nemu budet osushchestvlyat'sya dostup.
   S drugoj storony, pri dostupe  s  pomoshch'yu deskriptora fajla MS
DOS avtomaticheski sozdaet oblast' dannyh dlya fajla v proizvol'nom
meste. Zatem MS DOS sozdaet unikal'nyj 16-bitnyj kod nomera fajla
i vposledstvii etot "nomer" ispol'zuetsya funkciyami DOS dlya  iden-
tifikacii togo, s kakim iz otkrytyh fajlov proizvoditsya operaciya.
Vse chto nuzhno dlya nahozhdeniya fajla - eto standartnaya stroka puti,
v kotoroj mozhet byt' neobyazatel'noe imya nakopitelya i imena podka-
talogov dolzhny byt' razdeleny obratnoj  kosoj chertoj.  |ti stroki
otlichayutsya  ot  standartnogo zaprosa MS DOS tol'ko tem,  chto  oni
dolzhny zavershat'sya bajtom ASCII  0,  s  tem chtoby programma mogla
najti konec stroki (takie stroki nazyvayutsya strokami ASCIIZ).
   Operacii po peresylke dannyh iz ili v fajl trebuyut, chtoby byla
ukazana oblast' pamyati v kotoruyu ili iz kotoroj budut napravlyat'-
sya dannye. Takoj bufer opredelyaetsya otvedeniem emu mesta v pamyati


i ustanovkoj ukazatelya na ego pervyj  bajt (t.e. na mladshij adres
bufera  v pamyati).  Esli peredano slishkom mnogo dannyh, to  bufer
perepolnyaetsya i mozhet razrushit' dannye, raspolozhennye v sleduyushchih
adresah  pamyati.   Bufer mozhet ispol'zovat'sya  kak  promezhutochnyj
bufer, rabotayushchij tol'ko s nebol'shoj  porciej dannyh dlya operacij
chteniya ili zapisi. Ili bufer mozhet pomeshchat'sya v oblast' pamyati, v
kotoroj programma dejstvitel'no hranit i obrabatyvaet dannye.
   Funkcii dostupa cherez upravlyayushchij blok fajla opredelyayut prome-
zhutochnyj  bufer s pomoshch'yu ukazatelya, kotoroj vse  vremya  hranitsya
operacionnoj sistemoj.  |tot  bufer  nazyvaetsya  oblast' obmena s
diskom  (disk  transfer area) ili DTA.  K sozhaleniyu,  tehnicheskaya
dokumentaciya po IBM PC chasto  nazyvaet  terminom DTA ukazatel' na
bufer,  hotya  na samom dele pravil'no nazyvat' ego ukazatelem  na
DTA.  Posle togo kak ukazatel'  na  DTA ustanovlen s pomoshch'yu spe-
cial'noj funkcii, vse fajlovye operacii ispol'zuyut ego do teh por
poka on ne budet izmenen. S drugoj storony, funkcii, ispol'zuyushchie
deskriptor fajla, dolzhny ukazyvat' startovyj adres bufera  obmena
kazhdyj raz pri vyzove funkcii i  oni ignoriruyut ukazatel' na DTA,
ispol'zuemyj  funkciyami  upravlyayushchego bloka fajla.   Risunok  5-2
pokazyvaet dva metoda dostupa k fajlam.




   Programmy mogut ekonomit' chast' raboty, naznachaya nakopitel' po
umolchaniyu, na  kotorom  soderzhatsya  fajly  dannyh.  Esli v nachale
programmy  zaprosit'  u  pol'zovatelya kakoj nakopitel'  on  budet
ispol'zovat', to vposledstvii ne budet  somnenij k kakomu nakopi-
telyu sleduet obrashchat'sya.

   Vysokij uroven'.

   V privedennoj programme na Bejsike tekushchij nakopitel' po umol-
chaniyu pereklyuchaetsya s pomoshch'yu procedury na mashinnom yazyke. Proce-
dura  imeet dlinu vsego 7 bajtov.  Ona pomeshchaetsya v stroku X$,  a
peremennaya Z sluzhit ukazatelem na pervyj bajt procedury. V prilo-
zhenii  G ob®yasnyaetsya kak vstavlyat' assemblernye procedury v prog-
rammy na Bejsike.  Nomer nakopitelya ustanavlivaetsya v stroke 110,
prichem 0 = A, 1 = B i t.d.  Esli naznachit' nakopitelem po umolcha-
niyu nesushchestvuyushchij nakopitel', to oshibki ne budet, poetomu bud'te
vnimatel'ny. Ne pytajtes' ob®edinit' stroki 120 i 130 etoj proce-
dury, poskol'ku v etom sluchae interpretator Bejsika budet obraba-
tyvat' ih nepravil'no.

100 DEF SEG         'segment na nachalo oblasti Bejsika
110 NUM = 0         'vybiraem nakopitel' A
120 X$ = CHR$(180)+CHR$(14)+CHR$(178)+CHR$(NUM)+CHR$(205)+
         CHR(33)+CHR$(223)
130 Y = VARPTR(X$)  'poluchaem deskriptor stroki (adres v Y+1)
140 Z = PEEK(Y+1)+PEEK(Y+2)*256  'vychislyaem adres stroki
150 CALL Z          'vypolnyaem mashinnuyu proceduru


   Srednij uroven'.

   Funkciya EH preryvaniya 21H ustanavlivaet nakopitel' po  umolcha-
niyu. Nado prosto pomestit' nomer nakopitelya (0 = A, 1 = B i t.d.)
v  DL i vypolnit' preryvanie.  |ta funkciya vozvrashchaet v AL  chislo
nakopitelej na mashine. Otmetim, chto kogda u mashiny imeetsya tol'ko
odin nakopitel', to vozvrashchaetsya chislo 2. Luchshij sposob opredele-
niya chisla nakopitelej u mashiny opisan v [1.1.5].

   MOV  AH,0EH       ;nomer funkcii
   MOV  DL,1         ;kod dlya nakopitelya B
   INT  21H          ;ustanavlivaem nakopitel' po umolchaniyu

   Funkciya 19H preryvaniya 21H  soobshchaet  kakoj iz nakopitelej yav-
lyaetsya  nakopitelem po umolchaniyu.  Dlya etoj funkcii  net  vhodnyh
registrov. Pri vozvrate v AL soderzhitsya kodovyj nomer, gde 0 = A,
1 = B i t.d.




   Mozhno  sozdat'  fajl,  ne pomeshchaya v nego  nikakoj  informacii.
Sozdaetsya element kataloga, a dlina  fajla ustanavlivaetsya ravnoj
0.   Pri udalenii fajla sootvetstvuyushchij element kataloga na samom
dele ne udalyaetsya, on  prosto  stanovitsya  nedejstvuyushchim  za schet
izmeneniya pervogo bajta elementa (pervogo simvola imeni fajla) na
E5H. Vposledstvii etot element  mozhet byt' perezapisan pri sozda-
nii novogo fajla.  Vo vremya udaleniya fajla vnosyatsya takzhe izmene-
niya v tablicu razmeshcheniya fajlov, s tem chtoby sektora ispol'zuemye
etim fajlom byli dostupny dlya drugih fajlov. Samo soderzhimoe etih
sektorov pri etom ne stiraetsya.   Poetomu mozhno vosstanovit' uda-
lennyj  fajl - odnako preduprezhdaem, chto operacii s tablicej raz-
meshcheniya fajlov nado proizvodit' ochen' ostorozhno.

   Vysokij uroven'.

   Bejsik ne imeet special'noj komandy dlya sozdaniya fajla. Vmesto
etogo pri otkrytii fajla ukazannoe imya ishchetsya v kataloge i,  esli
ono ne najdeno, to sozdaetsya novyj fajl. Esli otkryt' novyj fajl,
a  zatem zakryt' ego ne proizvodya v nego zapisi, to on  ostanetsya
v kataloge s dlinoj 1 bajt i emu  budet otveden klaster diskovogo
prostranstva  (edinstvennyj bajt - eto simvol Ctrl-Z - ASCII 26 -
kotoryj ispol'zuetsya v kachestve priznaka konca standartnogo teks-
tovogo fajla). Detali operatora OPEN sm. v [5.3.3].
   Naoborot, operator CLOSE ne unichtozhaet fajl.  Vmesto etogo dlya
unichtozheniya fajla  ispol'zuetsya  operator  KILL.   Dlya togo chtoby
unichtozhit' fajl ego ne nado otkryvat'. Prosto pomestite imya fajla
v kavychkah, naprimer KILL "A:ACCOUNT.DAT".   Ili, esli fajl naho-
ditsya v drugom podkataloge, to nado ispol'zovat' standartnyj put'
k fajlu, naprimer KILL "A:\FINANCES\ACCOUNT.DAT". V oboih sluchayah
imya nakopitelya neobhodimo ukazyvat' tol'ko esli fajl nahoditsya ne
na nakopitele po umolchaniyu.  Otmetim, chto Vy ne mozhete vospol'zo-
vat'sya  etim metodom, chtoby udalit' podkatalog (kotoryj  yavlyaetsya
odnim iz vidov fajla) - vmesto etogo ispol'zujte RMDIR.


   Srednij uroven'.

   Fajl mozhet byt' sozdan  ili  unichtozhen  s  pomoshch'yu libo metoda
upravlyayushchego bloka fajla, libo metoda deskriptora fajla. Sozdanie
fajla odnim iz metodov ni  v  koej  mere  ne ogranichivaet budushchij
dostup k nemu tol'ko etim metodom.  No, poskol'ku odnovremenno  s
sozdaniem on otkryvaetsya, to pri sozdanii neobhodimo ispol'zovat'
tot metod, s pomoshch'yu kotorogo Vy budete rabotat' s etim fajlom na
etot raz. Kogda fajl sozdaetsya,  a zatem zakryvaetsya i pri etom v
nego nichego ne zapisyvaetsya, to emu sootvetstvuet element katalo-
ga s nulem v pole dliny fajla, odnako diskovoe prostranstvo etomu
fajlu  ne otvoditsya.  Vazhno ponimat', chto kogda  posledovatel'nyj
fajl otkryvaetsya dlya zapisi  (a  ne  dlya  dobavleniya)  dannyh, to
ispol'zuetsya  imenno  eta funkciya sozdaniya  fajla,  poetomu  fajl
obrezaetsya do nulevoj dliny i zatem polnost'yu perezapisyvaetsya.

Metod FCB:
   Funkciya 16H preryvaniya 21H sozdaet i otkryvaet fajl.  Sozdajte
FCB s imenem fajla i nakopitelya  i pust' DS:DX ukazyvaet na nego.
Zatem  vyzovite funkciyu.  Prosmatrivaetsya katalog i  esli  najden
sovpadayushchij element, to  snova  ispol'zuetsya  imenno etot element
kataloga, pri etom novyj fajl perekryvaet staryj s tem zhe imenem.

CHtoby izbezhat' neprednamerennogo  razrusheniya fajlov, snachala pro-
ver'te  na  nalichie fajla s takim imenem, ispol'zuya  funkciyu  11H
preryvaniya 21H [5.2.1].  Esli  net  fajla s takim imenem, to soz-
daetsya novyj element kataloga i v AL vozvrashchaetsya 0; esli katalog
polon, to v AL vozvrashchaetsya FF. CHtoby prisvoit' fajlu special'nye
atributy (naprimer, status tol'ko dlya chteniya) [5.2.6] ispol'zujte
rasshirennyj upravlyayushchij blok  fajla  [5.3.5].  Pri otkrytii novyj
fajl  inicializiruetsya  s nulevoj dlinoj i emu otvoditsya  klaster
diskovogo prostranstva. Vot primer:

;---v segmente dannyh
FCB       DB    1,'MYFILE  DAT',25 DUP(0)

;---proverka nalichiya takogo fajla
   MOV  AH,11H         ;funkciya poiska fajla
   LEA  DX,FCB         ;DS:DX ukazyvayut na FCB
   INT  21H            ;ishchem fajl
   CMP  AL,0           ;AL = 0 esli fajl sushchestvuet
   JE   WARN_USER      ;esli da, to soobshchaem ob etom
;---sozdanie fajla
   MOV  AH,16H         ;nomer funkcii sozdaniya fajla
   INT  21H            ;sozdaem fajl

   Dlya sozdaniya fajla so special'nymi atributami, naprimer statu-
som tol'ko dlya chteniya, nado ispol'zovat' rasshirennyj  upravlyayushchij
blok fajla. Bajt atributov fajla obsuzhdaetsya v [5.2.6]. K obychno-
mu  FCB  nado dobavit' 7-bajtnyj zagolovok, nachinaya s bajta  FFH,
zatem dolzhny sledovat'  5  bajtov  ASCII  0,  a zatem nuzhnyj bajt


atributov.   Dlya sozdaniya spryatannogo fajla neobhodimo, chtoby byl
ustanovlen bit 1 bajta atributov. CHtoby spryatat' fajl, otkrytyj v
privedennom primere, napishite:

FCB     DB     0FFH,5 DUP(0),2,1,'MYFILE  DAT',25 DUP(0)

   Funkciya  13H preryvaniya 21H unichtozhaet fajl.  Nado chtoby DS:DX
ukazyvali na neotkrytyj FCB i vypolnit'  funkciyu. Esli ne najdeno
fajla  s  ukazannym imenem, to v AL vozvrashchaetsya FF, inache 0.   V
imeni fajla mogut  ispol'zovat'sya  dzhokery  (znaki voprosa, no ne
zvezdochki) i v etom sluchae za odno obrashchenie k funkcii mozhet byt'
udaleno neskol'ko fajlov. Vot primer:

;---v segmente dannyh
FCB    DB     1,'MYFILE  DAT',25 DUP(0)

;---udalyaem fajl
   MOV  AH,13H           ;nomer funkcii udaleniya fajla
   LEA  DX,FCB           ;DS:DX ukazyvayut na FCB
   INT  21H              ;udalyaem fajl
   CMP  AL,0FFH          ;proverka na oshibku
   JE   DELETE_ERROR     ;uhod na obrabotku oshibki

Metod deskriptora fajla:
   Funkciya 3CH preryvaniya  21H  sozdaet  i  otkryvaet  novyj fajl
metodom  deskriptora  fajla.  DS:DX dolzhny ukazyvat'  na  stroku,
dayushchuyu put' k fajlu i  imya  fajla  v  standartnom formate MS DOS,
vklyuchaya  imya nakopitelya, esli fajl nahoditsya ne na nakopitele  po
umolchaniyu. Stroka dolzhna zavershat'sya bajtom ASCII 0. Bajt atribu-
tov  fajla  [5.2.6] pomestite v CX (0 - dlya  normal'nogo  fajla).
Zatem vypolnite funkciyu.  Pri  uspeshnom  vypolnenii flag perenosa

budet raven nulyu, a v AX budet vozvrashchen nomer novogo fajla.  Pri
vozniknovenii oshibki  flag  perenosa  ustanavlivaetsya v 1, a v AX
soderzhitsya kod oshibki, kotoryj mozhet byt' raven 3, esli ne najden
put', 4 - esli uzhe otkryty vse bufera dlya fajlov i 5 - esli kata-
log  polon ili fajl uzhe sushchestvuet so statusom tol'ko dlya chteniya.
Otmetim, chto esli v kataloge uzhe sushchestvuet  fajl s takim imenem,
to  sushchestvuyushchij  fajl obrezaetsya do nulevoj dliny, i  tem  samym
razrushaetsya.  Dlya izbezhaniya  oshibok nado predvaritel'no ispol'zo-
vat' funkciyu 4EH preryvaniya 21H dlya proverki.

;---v segmente dannyh
PATH     DB     'B:LEVEL1\LEVEL2\FILENAME.EXT',0

;---proverka nalichiya fajla v kataloge
   MOV  AH,4EH         ;funkciya poiska v kataloge
   LEA  DX,PATH        ;DS:DX ukazyvayut na put'
   INT  21H            ;proverka nalichiya fajla
   JNC  WARN_USER      ;esli est', to soobshchaem


;---sozdanie fajla
   MOV  AH,3CH         ;funkciya sozdaniya fajla
   MOV  CX,0           ;normal'nye atributy
   INT  21H            ;sozdaem fajl
   JC   OPEN_ERROR     ;uhod na obrabotku oshibki
   MOV  HANDLE,AX      ;zapominaem nomer fajla

   V  MS DOS 3.0 dobavlena novaya funkciya dlya sozdaniya fajla meto-
dom deskriptora fajla.  |to funkciya nomer 5BH preryvaniya 21H. Ona
rabotaet  v tochnosti tak zhe, kak i opisannaya funkciya 3CH, za isk-
lyucheniem togo, chto ona  vozvrashchaet  rasshirennye  kody oshibok, chto
pozvolyaet luchshe obrabatyvat' oshibochnye situacii.  Oni ob®yasneny v
[7.2.5].
   Dlya unichtozheniya fajla  metodom  deskriptora  fajla ispol'zujte
funkciyu  41H preryvaniya 21H.  I opyat' DS:DX dolzhny  ukazyvat'  na
stroku, dayushchuyu put' i imya fajla.  Dzhokery v imeni fajla ne dopus-
kayutsya.  Zatem vyzovite funkciyu.  Esli pri vozvrate flag perenosa
ustanovlen, to funkciya ne  vypolnena;  v etom sluchae AL budet so-
derzhat'  2,  esli fajl ne najden i 5 - esli proizoshla  oshi'ka  na
diske.  Otmetim, chto s pomoshch'yu  etoj funkcii Vy ne mozhete udalit'
fajl  so  statusom  tol'ko dlya chteniya;  izmenite  atributy  fajla
[5.2.6] pered ego udaleniem. Vot primer:

;---v segmente dannyh
PATH    DB    'B:LEVEL1\LEVEL2\FILENAME.EXT',0

;---unichtozhaem fajl
   MOV  AH,41H         ;nomer funkcii unichtozheniya
   LEA  DX,PATH        ;DS:DX ukazyvayut na put'
   INT  21H            ;unichtozhaem fajl
   JC   DELETE_ERROR   ;na obrabotku oshibki

   MS DOS versii 3.0  imeet  special'nuyu  funkciyu (5AH preryvaniya
21H)  dlya sozdaniya vremennogo "bezymyannogo" fajla.   Operacionnaya
sistema sama generiruet  imya  dlya  fajla  i proveryaet, chto takogo
fajla eshche net v kataloge. Pri etom isklyuchaetsya vsyakaya vozmozhnost'
chto pri sozdanii  vremennogo  fajla  budet  razrushen sushchestvuyushchij
fajl  s sovpadayushchim imenem.  Pri vhode DS:DX dolzhny ukazyvat'  na
stroku puti k katalogu,  v  kotorom  dolzhen byt' sozdan vremennyj
fajl.  Stroka dolzhna zavershat'sya obratnoj kosoj chertoj. Pomestite

atributy fajla v CX (obychno 0).   Pri vozvrate AX budet soderzhat'
nomer  fajla,  esli  tol'ko flag perenosa ne  ustanovlen, v  etom
sluchae AX soderzhit informaciyu  ob  oshibke. Proizvol'noe imya fajla
dobavlyaetsya  k koncu stroki puti.  |ta funkciya  mozhet  vozvrashchat'
rasshirennye kody oshibok, kotorye  sushchestvuyut tol'ko v MS DOS 3.0;
oni ob®yasnyayutsya v [7.2.5]. Fajl, sozdannyj etoj funkciej ne unich-
tozhaetsya avtomaticheski  -  programma  dolzhna ispol'zovat' funkciyu
41H  (sm.   vyshe).  V dannom primere programma sozdaet  vremennyj
fajl, a zatem unichtozhaet ego:


;---v segmente dannyh
PATH   DB    'B:LEVEL1\LEVEL2\',12 DUP(0)

;---sozdaem vremennyj fajl
   MOV  AH,5AH         ;nomer funkcii
   LEA  DX,PATH        ;DS:DX ukazyvayut na put'
   INT  21H            ;sozdaem vremennyj fajl
   JC   CREATION_ERROR ;uhod na obrabotku oshibki
    .
    .
   MOV  AH,41H         ;nomer funkcii
   LEA  DX,PATH        ;DS:DX ukazyvayut na put'
   INT  21H            ;unichtozhaem vremennyj fajl
   JC   DELETION_ERROR ;uhod na obrabotku oshibki




   "Otkryt'" fajl - eto znachit  sozdat'  nebol'shie  bloki pamyati,
kotorye  budut soderzhat' informaciyu o fajle i sluzhit' promezhutoch-
noj stanciej (buferom), cherez  kotoruyu  dannye budut peredavat'sya
mezhdu fajlom i pamyat'yu.  YAzyki vysokogo urovnya avtomaticheski soz-
dayut dlya Vas eti bloki, a  yazyk  assemblera  -  net. Pri otkrytii
fajla katalog proveryaetsya na ego nalichie.  Esli fajla najden,  to
MS DOS beret informaciyu  iz  kataloga  o  razmere i date sozdaniya
fajla.  Zatem, pri zakrytii fajla, sistema obnovlyaet informaciyu v
kataloge. Zakrytie fajla takzhe ochishchaet vse sistemnye bufera pere-
nosa, posylaya na disk ostavshuyusya informaciyu.  Esli Vy ne zakroete
fajl pered zaversheniem programmy,  to eto mozhet privesti k potere
dannyh.
   Esli programma rabotaet so mnogimi fajlami, to nado  postoyanno
imet' vvidu skol'ko imeetsya odnovremenno otkrytyh fajlov.  MS DOS
2.1 pozvolyaet imet' do 99 odnovremenno otkrytyh fajlov, prichem po
umolchaniyu tol'ko 8 (izmenite  eto  chislo s pomoshch'yu komandy MS DOS
FILES).  Bejsik pozvolyaet imet' ne bolee 15 otkrytyh fajlov. Kazh-
dyj fajl zanimaet mesto dlya bloka  parametrov i bufera. Poskol'ku
pamyat' dlya kazhdogo fajla otvoditsya otdel'no pered tem, kak  fajly
otkryvayutsya, to eta  pamyat'  nedostupna  dlya  programm, dazhe esli
ukazannoe  chislo  fajlov ne ispol'zuetsya v nastoyashchij moment.   Po
etoj prichine Vy mozhete ekonomit' pamyat', ustanavlivaya maksimal'no
dopustimoe chislo otkrytyh fajlov imenno takim, kotoroe trebuetsya,
s pomoshch'yu opisannogo metoda.

   Vysokij uroven'.

   Pri otkrytii fajla v Bejsike idet poisk v kataloge i esli fajl
ne najden, to sozdaetsya novyj fajl  s dannym imenem.  Imeetsya dva
sposoba  zapisi operatora otkrytiya fajla i v bol'shinstve  sluchaev
oba eti sposoba ekvivalentny. Edinstvennoe otlichie sostoit v tom,
chto odin iz etih sposobov bolee zakodirovan, v to vremya kak  dru-
goj blizhe k estestvennomu  yazyku.   V  oboih operatorah Vy dolzhny
ukazat' po men'shej mere tri sorta informacii. Vo-pervyh trebuetsya
imya fajla i, poskol'ku eto  stroka,  ono  dolzhno byt' zaklyucheno v


kavychki.  Vo-vtoryh, chislo, nachinaya s 1, prisvaivaetsya fajlu, kak
identifikacionnyj nomer, po  kotoromu drugie operatory chitayut ili
pishut v fajl. I v-tret'ih Vy dolzhny ukazat' dlya kakoj celi otkry-
vaetsya dannyj fajl, t.e. otkryt  li on dlya pryamogo ili dlya posle-
dovatel'nogo dostupa.  Dlya otkrytiya fajla MYFILE.TXT dlya zapisi v
posledovatel'nyj fajl,  prichem  etot  fajl  budet  imet' nomer 2,
zapishite ili

   OPEN "O",#2,"MYFILE.TXT"

ili

   OPEN "MYFILE.TXT" FOR OUTPUT AS #2

Otmetim, chto v oboih sluchayah nomer 2 otnositsya k buferu fajla #2.
CHislo mozhet byt' lyubym, ne prevoshodyashchim  chisla razreshennyh bufe-
rov dlya fajlov. Esli podderzhivaetsya odnovremennaya rabota s shest'yu
fajlami, to chislo dolzhno byt' v intervale ot 0 do 6. Odnako bufer
fajla nomer 1 ne obyazatel'no ispol'zovat' ran'she, chem fajla nomer
2.  Po umolchaniyu Bejsik ustanavlivaet  chislo buferov ravnoe 8, no

Vy mozhete izmenit' eto chislo na drugoe ot 4 do 15. Iz etih fajlov
chetyre ispol'zuyutsya Bejsikom dlya svoih nuzhd, poetomu po umolchaniyu
tol'ko  4  fajla dostupny Vam dlya vvoda/vyvoda.  Dlya  togo  chtoby
ustanovit' chislo  dostupnyh  buferov  ispol'zujte parametr F: pri
zapuske  Bejsika.  Naprimer, esli Vy pri starte Bejsika  napishite
BASICA/F:10, to budet sozdano  10  buferov, shest' iz kotoryh dos-
tupny dlya fajlovyh operacij.
   Vtoroj parametr, S:, ustanavlivaet razmer buferov fajla.   Vse
bufera imeyut odin i tot zhe razmer.  Po umolchaniyu beretsya razmer v
128 bajtov, odnako dopustimy razmery do 32767 bajtov.  Dlya fajlov
posledovatel'nogo dostupa etot  razmer mozhet byt' ustanovlen rav-
nym 0, chto pozvolyaet nemnogo sekonomit' pamyat'. Dlya fajlov pryamo-
go dostupa on dolzhen byt' ne men'she maksimal'nogo razmera zapisi.
Otmetim,  chto eschi razmer zapisi raven 512 bajtam i razmer bufera
tozhe 512 bajt, to eto  privodit  k  uskoreniyu  diskovyh operacij.
Komanda BASICA/S:512/F:10 otkryvaet 10 buferov razmerom 512 bajt.
Kazhdyj fajl trebuet 188  bajtov  plyus  razmer bufera, poetomu dlya
takoj konfiguracii potrebuetsya 7K pamyati.  CHislo buferov ne mozhet
byt' bol'she, chem razresheno imet' otkrytyh fajlov v DOS.

Kodirovannaya forma:
   Pervaya iz form operatora OPEN ispol'zuet  odnu bukvu dlya oboz-
nacheniya  zhelaemogo tipa operacij nad fajlom.  Imeetsya tri vozmozh-
nosti:

   "O"   otkryt' fajl s posledovatel'nym dostupom dlya vyvoda
   "I"   otkryt' fajl s posledovatel'nym dostupom dlya vvoda
   "R"   otkryt' fajl s pryamym dostupom dlya vvoda/vyvoda

Posledovatel'nye fajly ne mogut  zapisyvat'sya,  kogda oni otkryty
dlya chteniya i naoborot. V tipichnyh sluchayah, posledovatel'nye fajly
otkryvayutsya dlya  chteniya,  zatem  schityvayutsya  celikom  v pamyat' i


zakryvayutsya.  Posle togo kak neobhodimye izmeneniya vneseny,  fajl
snova otkryvaetsya, no teper' dlya  vyvoda i zapisyvaetsyaobratno na
disk,  perekryvaya to, chto bylo zapisano v ego sektorah i, vozmozh-
no, zahvatyvaya novye sektora.
   Sleduet otmetit' neskol'ko momentov,  otnosyashchihsya k etoj forme
operatora  OPEN.  Imya fajla dolzhno soderzhat' imya nakopitelya, esli
fajl ne najden na nakopitele  po  umolchaniyu  (t.e.  nakopitele, s
kotorogo zapushchen Bejsik).  Imya fajla mozhet takzhe soderzhat' put' k
fajlu, nahodyashchemusya v  podkataloge,  naprimer OPEN "I",#1,"A:\LE-
VEL1\LEVEL2\MYFILE.TXT". Krome togo, Vy mozhete pomestit' ukazanie
razmera zapisi v konce operatora  OPEN "R",#3,"MYFILE.TXT",52.  V
etom  sluchae  kazhdaya  zapis' budet zanimat'  52  bajta  diskovogo
prostranstva.  Esli v  operatore  FIELDS  ne  ispol'zuyutsya vse 52
bajta, to ostatok propadet.  |tot parametr sushchestvenen pri opera-
ciyah s fajlami pryamogo  dostupa.  Bol'shinstvo  operacij s fajlami
posledovatel'nogo dostupa ne trebuyut ukazaniya dliny zapisi, odna-
ko Vy mozhete uskorit' fajlovye  operacii, ustanoviv razmer zapisi
ravnym  512 bajtam.  Dlina zapisi mozhet byt' v diapazone ot 1  do
32767 bajtov i po umolchaniyu ravna 128 bajtam.

Forma estestvennogo yazyka:
   Vtoraya forma operatora OPEN delaet sovershenno to zhe samoe, chto
i  pervaya, no ispol'zuet polnye slova.  Vmesto togo, chtoby pisat'
"O" ili "I", Vy dolzhny  pisat'  INPUT  ili  OUTPUT (bez kavychek),
naprimer,  OPEN "FILENAME" FOR INPUT AS #1.  Dlya fajlov s  pryamym
dostupom ne ukazyvaetsya etot  parametr:  OPEN "MYFILE.TXT" AS #2.

Krome togo, Vy mozhete ukazat' rezhim APPEND, chtoby zapisat' dannye
nachinaya s konca posledovatel'nogo fajla, ne unichtozhaya uzhe sushchest-
vuyushchih  dannyh: OPEN "B:MYFILE.TXT" FOR APPEND AS #3.  Kak i  dlya
pervoj formy v operatore mozhet byt'  ukazana neobyazatel'naya dlina
zapisi. Nado prosto dobavit' v kgnce operatora LEN = chislo.  Nap-
rimer OPEN "C:MYFILE.TXT" AS #1  LEN  = 52 otkryvaet fajl pryamogo
dostupa s zapisyami dlinoj 52 bajta.
   CHasto  programma  dolzhna poluchat' imya  fajla  ot  pol'zovatelya
programmy.  CHtoby  ispol'zovat'  eto  imya  fajla v operatore OPEN
prosto  podstav'te vmesto stroki imeni fajla imya stroki, soderzha-
shchej eto imya. Pri etom neobhodima proverka na pravil'nost' vveden-
nogo imeni.

100 INPUT "Enter file name: ",F$  'poluchaem imya fajla
110 IF INSTR(F$,".") <> 0 THEN 130  'est' li rasshirenie?
120 IF LEN(F$) > 8 THEN 500 ELSE 150  'dlinnee 8 simvolov?
130 IF LEN(F$) > 12 THEN 500      'dlinnee 12 simvolov?
140 IF LEN(F$) - INSTR(F$,".") > 3 THEN 500 'tip dlinnee 3-h
150 OPEN F$ FOR INPUT AS #1       'otkryvaem fajl
 .
 .
500 INPUT "Improper filename - enter another: ",F$
510 GOTO 110                 'esli imya nevernoe, novyj zapros

Zakrytie fajla:
   Zakrytie  fajla trivial'no.  CHtoby zakryt' vse otkrytye  fajly
napishite CLOSE. CHtoby  zakryt'  opredelennyj  fajl  ili neskol'ko


fajlov  napishite  CLOSE #1 ili CLOSE #1, #3.  Vazhno  zakryt'  vse
fajly pered zaversheniem  programmy.   Esli etogo ne sdelat', to v
fajle mogut ostat'sya dannye, kotorye ne zapisany na disk.   Otme-
tim, chto komandy  END,  NEW,  RESET,  SYSTEM  i RUN zakryvayut vse
bufera fajlov, no ne ochishchayut eti bufera. Uzhe zakrytyj fajl vsegda
mozhet byt' snova otkryt s ispol'zovaniem lyubogo dostupnogo bufera
fajla.

   Srednij uroven'.

   MS  DOS obespechmvaet razlichnye funkcii dlya otkrytiya i zakrytiya
fajla, v zavisimosti ot togo ispol'zovala li programma dlya dostu-
pa  k fajlu metod upravlyayushchego bloka fajla ili metod  deskriptora
fajla.  V oboih sluchayah mogut  byt' otkryty tol'ko fajly, kotorye
sushchestvovali do etogo.  Dlya sozdaniya novyh fajlov sushchestvuet spe-
cial'naya funkciya [5.3.2].

Metod FCB:
   Funkciya 0FH preryvaniya  21H  otkryvaet  sushchestvuyushchij  fajl. Vy
dolzhny  snachala  sozdat' upravlyayushchij blok fajla, kak  pokazano  v
[5.3.5]. Pered otkrytiem FCB  dolzhen soderzhat' tol'ko imya fajla i
imya  nakopitelya (0 = po umolchaniyu, 1 = A i t.d.).   DS:DX  dolzhny
ukazyvat' na FCB, a zatem nado vypolnit' funkciyu. Pri vozvrate AL
budet  soderzhat'  0, esli fajl uspeshno otkryt i FF, esli fajl  ne
najden.  Esli dlya ukazaniya nakopitelya ispol'zuetsya 0, to on budet
zamenen na kod, sootvetstvuyushchij nakopitelyu po umolchaniyu.
   Tol'ko  posle togo kak fajl otkryt Vy dolzhny ustanovit' razmer
zapisi (po umolchaniyu -  128  bajt),  a  takzhe polya zapisi pryamogo
dostupa  i tekushchej zapisi (oni obsuzhdayutsya v razdele, otnosyashchemsya
k operaciyam s posledovatel'nym  i  pryamym dostupom). Pri otkrytii
pole  tekushchego  bloka  zapolnyaetsya nulem, a polya  daty i  vremeni
informaciej iz kataloga.

   CHtoby zakryt' fajl s pomoshch'yu metoda FCB, nado ustanovit' DS:DX
na  otkrytyj FCB i vyzvat' funkciyu 10H preryvaniya 21H.  Pri udache
informaciya o razmere fajla, date i vremeni budet zapisana v kata-
log,  a  v AL budet vozvrashchen 0.  Odnako esli imya fajla ne  budet
obnaruzheno v kataloge ili ono budet  najdeno v drugoj pozicii, to
izmeneniya na diske budut indicirovany vozvratom FF v AL.

;---v segmente dannyh
FCB     DB     1,'FILENAMEEXT',25 DUP(0)

;---otkrytie fajla
   MOV  AH,0FH        ;nomer funkcii
   LEA  DX,FCB        ;DS:DX ukazyvayut na FCB
   INT  21H           ;otkryvaem fajl
   CMP  AL,0          ;proverka na oshibku
   JNE  OPEN_ERROR    ;na obrabotku oshibki
    .
    .


;---zakrytie fajla
   MOV  AH,10H        ;nomer funkcii
   LEA  DX,FCB        ;DS:DX ukazyvayut na FCB
   INT  21H           ;zakryvaem fajl
   CMP  AL,0          ;proverka na oshibku
   JNE  CLOSE_ERROR   ;na obrabotku oshibki

Metod deskriptora fajla:
   Dlya  otkrytiya  fajlov ispol'zujte funkciyu 3DH preryvaniya  21H.
DS:DX dolzhny ukazyvat' na stroku,  dayushchuyu put' i imya fajla, vklyu-
chaya imya nkakopitelya, esli eto neobhodimo.  Vsya stroka dolzhna byt'
ne dlinnee 63-h bajtov i zavershat'sya simvolom ASCII 0.  V AL nado
pomestit'  kod dostupa, prichem 0 otkryvaet fajl dlya  chteniya, 1  -
dlya zapisi, a 2 - dlya chteniya/zapisi. Pri vozvrate AX budet soder-
zhat' 16-bitnyj nomer fajla, po kotoromu fajl vposledstvii identi-
ficiruetsya. Fajlovyj ukazatel'  ustanavlivaetsya  na nachalo fajla.
Razmer zapisi ustanavlivaetsya ravnym 1 bajtu - eto svyazano s tem,
chto operacii pryamogo dostupa pri ispol'zovanii metoda deskriptora
fajla ne imeyut special'nyh buferov: na samom dele fajly s  pryamym
dostupom rassmatrivayutsya kak  posledovatel'nye  i s nimi rabotayut
odni  i te zhe funkcii.  |ta funkciya pozvolyaet otkryvat' kak obych-
nye, tak i spryatannye fajly.  Pri vozvrate flag perenosa raven 0,
esli fajl otkryt uspeshno.  V protivnom sluchae flag perenosa usta-
navlivaetsya, a AX soderzhit 2  -  esli  fajl  ne  najden, 4 - esli
programma  hochet otkryt' slishkom mnogo fajlov, 6 - pri oshibke  na
diske i 12 - esli nepravil'no  ukazan  kod dostupa v AL. Vot pri-
mer:

;---v segmente dannyh
PATH    DB    'A:LEVEL1\FILENAME.EXT',0

;---otkryvaem fajl dlya chteniya/zapisi
   MOV  AH,3DH         ;nomer funkcii
   MOV  AL,2           ;otkryvaem dlya chteniya/zapisi
   LEA  DX,PATH        ;DS:DX ukazyvayut na put'
   INT  21H            ;otkryvaem fajl
   JC   OPEN_ERROR     ;uhod na obrabotku oshibok
   MOV  HANDLE,AX      ;sohranyaem nomer fajla

   Funkciya  3EH  preryvaniya 21H zakryvaet fajl, otkrytyj  metodom
deskriptora fajla.  Nado prosto  pomestit' nomer fajla v BX i vy-
polnit' funkciyu.  Pri vozvrate flag perenosa raven 0, esli vse  v
poryadke, inache on raven 1, a AX  =  6, esli ukazan nevernyj nomer
fajla.

;---zakrytie fajla
   MOV  AH,3EH       ;nomer funkcii
   MOV  BX,HANDLE    ;nomer fajla
   INT  21H          ;zakryvaem fajl
   JC   CLOSE_ERROR  ;uhod na obrabotku oshibki


   Funkciya 45H preryvaniya 21H sozdaet vtoroj deskriptor fajla  iz
sushchestvuyushchego  otkrytogo  deskriptora.   V  BX dolzhen byt' ukazan
sushchestvuyushchij  nomer, a v AX budet vozvrashchen novyj.   Funkciya  46H
preryvaniya 21H svyazyvaet  vtoroj  deskriptor  (pomeshchaemyj v CX) s
otkrytym  fajlom (nomer kotorogo v BX) takim obrazom, chto  pervyj
budet otnosit'sya k tomu zhe fajlu i ustrojstvu, chto i poslednij.




   Pereimenovanie fajla mozhet zaklyuchat'sya lish' v izmenenii pervyh
11-ti simvolov elementa kataloga.   Odnako v drevovidnom kataloge
ves'  element kataloga mozhet byt' perenesen v drugoj  podkatalog,
pereopredelyaya tem samym put'  k  fajlu.  Odna  komanda  mozhet kak
pereimenovat' fajl, tak i perenesti ego v drugoj katalog.

   Vysokij uroven'.

   V Bejsike fajl pereimenovyvaetsya komandoj NAME. S pomoshch'yu etoj
komandy on mozhet byt' takzhe perenesen  v drugoj katalog. Napishite
snachala sushchestvuyushchee imya, a zatem novoe imya fajla, oba  zaklyuchen-
nye v kavychki, naprimer NAME  "OLDFILE.EXT"  AS "NEWFILE.EXT".  V
etom  sluchae  budet pereimenovan fajl v kornevom  kataloge.   Dlya
izmeneniya imen fajlov,  raspolozhennyh  v podkatalogah, mogut byt'
ispol'zovany puti k fajlu.  Naprimer, NAME "B:LEVEL1\OLDFILE.EXT"
AS "B:LEVEL1\NEWFILE.EXT"  izmenyaet  imya  fajla v podkataloge LE-
VEL1.
   Otmetim, chto dlya novogo imeni fajla dolzhen byt' ukazan  polnyj
put'.  Esli Vy zapishete  NAME  "B:LEVEL1\OLDFILE.EXT"  AS "NEWFI-
LE.EXT",  to fajl budet ne tol'ko pereimenovan, no i perenesen  v
kornevoj katalog.  Dlya  perenosa  fajla  iz  odnogo podkataloga v
drugoj  bez izmeneniya ego imeni napishite komandu NAME "A:SUBDIR1-
\OLDFILE.EXT" AS  "A:SUBDIR2\OLDFILE.EXT".  Takim  metodom nel'zya
perenesti fajl s diska na disk.  Poskol'ku fajly, raspolozhennye v
raznyh katalogah mogut imet' odno i to zhe imya, to vozmozhna oshibka
pri popytke perenosa fajlov s odinakovymi imenami.  V etom sluchae
budet vozvrashchen kod oshibki 58 [5.4.8].

   Srednij uroven'.

   MS DOS mozhet pereimenovyvat' fajly, ispol'zuya kak metod uprav-
lyayushchego bloka fajla, tak i metod deskriptora fajla. Pervyj iz nih
mozhet primenyat'sya tol'ko k fajlam,  raspolozhennym v tekushchem kata-
loge.

Metod FCB:
   Ispol'zujte funkciyu 17H preryvaniya 21H. DS:DX dolzhny ukazyvat'
na otkrytyj upravlyayushchij blok  fajla.  Pomestite novoe imya fajla v
FCB,  nachinaya  so smeshcheniya 11H (eto "rezervnaya"  oblast'  bloka).
Novoe imya mozhet ispol'zovat'  simvol  "?", v etom sluchae simvoly,
nahodyashchiesya  v etih poziciyah, ne budut izmenyat'sya.  Pri vozvrate,
esli novoe imya uzhe sushchestvovalo v kataloge, to AL budet ravno FF,
inache  AL  =  0.  V primere imya fajla  ACCOUNTS.DAT  menyaetsya  na
DEBTS.DAT.


;---v segmente dannyh
FCB       DB      'FILENAMEEXT',25 DUP(0)
NEWNAME   DB      'NEWNAME EXT',   ;11 simvolov novogo imeni

;---pomeshchaem novoe imya fajla v peremennuyu NEWNAME
      MOV  SI,OFFSET NEWNAME   ;DS:SI ukazyvayut na novoe imya
      MOV  AX,SEG FCB          ;ES:DI ukazyvayut na FCB
      MOV  ES,AX               ;
      MOV  DI,OFFSET FCB       ;
      ADD  DI,11H              ;nachinaem so smeshcheniya 11H
      MOV  CX,11               ;imya fajla soderzhit 11 simvolov

REP   MOVSB                    ;perenosim 11 bajtov
      LEA  DX,FCB              ;DS:DX ukazyvayut na FCB
      MOV  AH,17H              ;funkciya izmeneniya imeni
      INT  21H                 ;izmenyaem imya
      CMP  AL,0FFH             ;proverka na oshibku
      JE   RENAME_ERROR        ;uhod na obrabotku oshibki

Metod deskriptora fajla:
   Funkciya 56H preryvaniya 21H pereimenovyvaet i peremeshchaet fajly.
DS:DX dolzhny ukazyvat' na stroku, dayushchuyu put' i imya pereimenuemo-
go  fajla  (do 63-h simvolov) i zavershayushchuyusya simvolom  ASCII  0.
ES:DI dolzhny ukazyvat' na vtoruyu stroku, kotoraya daet novye imya i
put' fajla.  Imena  nakopitelej,  esli  oni  prisutstvuyut, dolzhny
sovpadat'.   Esli  puti razlichny, to fajl perenonositsya v  drugoj
podkatalog.  CHtoby perenesti fajl bez pereimenovaniya nado vo vto-
roj stroke ukazat' to zhe samoe imya, no drugoj put'. Pri vozvrate,
esli proizoshla oshibka,  to  ustanavlivaetsya  flag  perenosa, a AX
budet soderzhat' 3 - esli odin iz putej ne najden, 5 - pri  oshibke
na diske i 17 - pri popytke  perenosa mezhdu raznymi nakopitelyami.
V  primere  fajl ACCOUNTS.DAT perenositsya iz podkataloga GAINS  v
podkatalog LOSSES.

;---v segmente dannyh
OLDPATH   DB   'A:GAINS\ACCOUNTS.DAT',0
NEWPATH   DB   'A:LOSSES\ACCOUNTS.DAT',0

;---izmenenie puti fajla
   LEA  DX,OLDPATH          ;DS:DX ukazyvayut na staryj put'
   MOV  AX,SEG NEWPATH      ;ES:DI ukazyvayut na novyj put'
   MOV  ES,AX               ;
   MOV  DI,OFFSET NEWPATH   ;
   MOV  AH,56H              ;nomer funkcii
   INT  21H                 ;perenosim fajl
   JC   ERROR_ROUTINE       ;uhod na obrabotku oshibki




   YAzyki vysokogo urovnya, takie kak  Bejsik, vypolnyayut podgotovi-
tel'nuyu rabotu dlya fajlovyh operacij avtomaticheski.  Odnako prog-
rammy na yazyke assemblera imeyut  dostatochno  raboty pered tem kak


sozdat' ili otkryt' fajl. Trebovaniya otlichayutsya, v zavisimosti ot
togo ispol'zuetsya li dlya dostupa k fajlu metod upravlyayushchego bloka
fajla ili metod deskriptora fajla.  Dlya oboih metodov Vam neobho-
dimo stroku ili blok parametrov,  ukazyvayushchih na fajl i bufer dlya
perenosa  dannyh.  MS DOS predostavlyaet razlichnye nabory  funkcij
chteniya/zapisi dlya dvuh metodov.

   Srednij uroven'.

Metod upravlyayushchego bloka fajla:
   |tot metod dostupa k  fajlam  trebuet,  chtoby  Vy sozdali blok
parametrov,  kotryj pervonachal'no dolzhen soderzhat' takuyu informa-
ciyu, kotoraya pozvolyaet  najti  fajl  v  kataloge.  Hotya FCB imeet
mnogo  polej, voobshche govorya, tol'ko nekotorye iz nih dolzhny  byt'
zapolneny; MS DOS zapolnyaet bol'shinstvo  ostal'nyh polej informa-
ciej posle togo, kak fajl otkryvaetsya.  Otmetim, chto k nachalu FCB
mozhet dobavlyat'sya special'noe pole dlya sozdaniya rasshirennogo FCB,
kotoryj ob®yanyaetsya nizhe. Vot struktura FCB:

Nakopitel' (DB)      CHislo,   opredelyayushchee  na  kakom  nakopitele
                     budet iskat'sya  fajl,  1  =  A, 2 = B i t.d.
                     Esli  ukazan  0,  to beretsya  nakopitel'  po
                     umolchaniyu, a zatem sistema zamenyaet 0 na kod
                     etogo nakopitelya.

Imya i rasshirenie     Vos'mibajtnoe  imya  fajla,  vyravnennoe   po
(11 bajtov)          levomu krayu dolzhno  byt' dopolneno probelami
                     (ASCII 32), esli ono men'she 8 bajtov.  To zhe
                     otnositsya i k trehbajtnomu rasshireniyu. Mezhdu
                     nimi ne dolzhna stoyat' tochka.

Tekushchij blok (DW)    DOS organizuet fajly blokami po 128 zapisej,
                     pronumerovannyh ot 0 do  127. Naprimer, sis-
                     tema rassmatrivaet zapis' #129 fajla pryamogo
                     dostupa, kak zapis' #0  bloka #1 (otschet kak
                     dlya zapisej, tak i dlya blokov vedetsya s  0).
                     V fajlah  net  special'nyh  ogranichitelej ni
                     dlya  blokov  ni dlya zapisej.   Vmesto  etogo
                     smeshchenie dlya blokov  i  zapisej  vychislyaetsya
                     ishodya  iz dliny zapisi, kotoraya  ustanavli-
                     vaetsya sleduyushchim polem FCB.

Razmer zapisi (DW)   Vse funkcii MS DOS, svyazannye  s chteniem ili
                     zapis'yu v fajl, rabotayut v terminah  zapisi.
                     Dlya  fajlov  pryamogo  dostupa  vazhno,  chtoby
                     razmer  zapisi byl ustanovlen ravnym razmeru
                     zapisej, pomeshchennyh v  fajl.  Dlya posledova-
                     tel'nyh fajlov razmer zapisi ne stol' vazhen,
                     odnako malen'kij  razmer zapisi budet zamed-
                     lyat'  diskovye operacii.   Poskol'ku  razmer
                     sektora 512 bajtov,  to optimal'nym yavlyaetsya
                     razmer zapisi 512 bajtov.  Sistema avtomati-


                     cheski  pomeshchaet  znachenie  po  umolchaniyu 80H
                     (128)  v pole dliny zapisi pri otkrytii faj-
                     la.  Poetomu ne zabud'te ustanovit' eto pole
                     posle otkrytiya fajla.

Razmer fajla (DD)    Razmer ukazyvaetsya s tochnost'yu do bajta. |to
                     pole zapolnyaetsya  sistemoj pri otkrytii faj-
                     la.

Data fajla (DW)      Data zapisyvaetsya sistemoj pri otkrytii FCB.
                     Ee format priveden v [5.2.5].

Tekushchaya zapis' (DB)  Tekushchaya  zapis'  ispol'zuetsya   sovmestno  s
                     polem tekushchego bloka. Zapisi numeruyutsya ot 0
                     do 127.  Zapis' pryamogo dostupa #200, raspo-
                     lozhennaya  v  bloke  1, imeet  nomer  tekushchej
                     zapisi ravnyj 71 ((200 - 128) - 1).

Nomer zapisi prya-    Vmesto togo, chtoby  trebovat'  ot programmy,
mogo dostupa (DD)    chtoby ona vychislyala tekushchie znacheniya bloka i
                     zapisi dlya  fajla  pryamogo  dostupa,  MS DOS
                     delaet  etu  rabotu sama.  Pri  operaciyah  s
                     fajlami  pryamogo  dostupa  prosto  pomestite
                     nomer  zapisi  v eto 4-hbajtnoe  pole.   Pri
                     vypolnenii operacii s fajlom pryamogo dostupa

                     MS DOS pomestit nuzhnye znacheniya v polya teku-
                     shchego bloka i tekushchej  zapisi.   Pomnite, chto
                     starshij bajt raspolozhen v starshej yachejke.

Svyaz'  mezhdu polyami tekushchej zapisi, tekushchego bloka i nomer zapisi
pryamogo dostupa pokazana na ris. 5-3.
   Prostejshij put' sozdat' FCB  kak  peremennuyu v segmente dannyh
programmy.   Esli imya otkryvaemogo fajla ne menyaetsya, to eto  imya
mozhet byt' pryamo zapisano v eto  pole.  Ostatok bloka inicializi-
rujte bajtami ASCII 0.  Tol'ko posle togo kak FCB budet otkryt (s
pomoshch'yu funkcii 0FH preryvaniya  21H,  kak  pokazano v [5.3.3]) Vy
dolzhny zapisat' v blok ostal'nuyu informaciyu. Otmetim, chto FCB dlya
raboty s  prostym  posledovatel'nym  fajlom  s  dlinoj zapisi 128
bajtov  ne trebuet dal'nejshih prigotovlenij.  Posle sozdaniya  FCB
dal'nejshie operacii trebuyut, chtoby DS:DX ukazyvali na nego. Pros-
tejshaya forma ego takaya:

FCB      DB     1,'FILENAMEEXT',25 DUP(0)

Mozhno takzhe sozdat' FCB kak strukturu:

FCB           STRUC
DRIVE_NUM     DB     0
FILE_NAME     DB     8 DUP(?)
FILE_EXT      DB     3 DUP(?)
BLOCK_NUM     DW     0
RECORD_SIZE   DW     0


FILE_SIZE     DD     0
FILE_DATE     DW     0
RESERVED      DB     10 DUP(0)
CURRENT_REC   DB     0
RANDOM_REC    DD     0
FCB           ENDS

Pri takom podhode programme proshche pomeshchat' dannye v FCB, poskol'-
ku metki sushchestvuyut dlya kazhdogo polya.  V zavisimosti ot tipa faj-
lovyh operacij na polya mogut nakladyvat'sya sleduyushchie ogranicheniya:

   1.   Dlya  fajlov pryamogo dostupa Vy dolzhny  ustanovit'  razmer
zapisi i nomer zapisi v pole zapisi pryamogo dostupa.
   2. Dlya dostupa  k  posledovatel'nym  fajlam s nachala Vy dolzhny
ustanovit'  tol'ko razmer zapisi, pri uslovii, chto Vy inicializi-
rovali polya tekushchego bloka i tekushchej  zapisi v 0 (prosto obnulite
ves'  FCB, za isklyucheniem imen nakopitelya i fajla).  Pri otkrytii
pole razmera zapisi budet ustanovleno ravnym 128, esli eto znache-
nie ustarivaet Vas, to dal'nejshaya podgotovka ne nuzhna.
   3.   Dlya  dostupa k posledovatel'nomu fajlu s serediny  ili  s
konca Vy dolzhny ustanovit' polya  tekushchego  bloka i tekushchej zapisi
(v etom sluchae Vasha programma dolzhna budet proizvodit' vychisleniya
sama).

   Prefiks programmnogo segmenta [1.3.0] imeet dostatochno bol'shoe
pole,  chtoby soderzhat' upravlyayushchij blok fajla.  |to  prostranstvo
predostavlyaetsya dlya kazhdoj  programmy, poetomu ekonomno ispol'zo-
vat' ego, osobenno v programmah tipa .COM.  Pole FCB  raspolozheno
so smeshcheniem 5CH v prefikse programmnogo  segmenta.  V programmah
COM  ispol'zujte  ORG dlya sozdaniya FCB sleduyushchim  obrazom  (zdes'
pomechen takzhe ispol'zuemyj po umolchaniyu DTA, kotoryj budet obsuzh-
dat'sya nizhe):

;---v nachale kodovogo segmenta
             ORG  5CH
FCB          LABEL   BYTE
DRIVE_NUM    DB   0
FILE_NAME    DB   8 DUP(?)
FILE_EXT     DB   3 DUP(?)
BLOCK_NUM    DW   0
RECORD_SIZE  DW   0
FILE_SIZE    DD   0
FILE_DATE    DW   0
RESERVED     DB   10 DUP(0)
CURRENT_REC  DB   0
RANDOM_REC   DD   0
             ORG  80H
DTA          LABEL   BYTE
             ORG  100H
             ASSUME CS:CSEG, DS:DSEG, SS:SSEG
              ...


   Rasshirennyj FCB ispol'zuetsya dlya sozdaniya ili dostupa k fajlu,
imeyushchemu special'nye atributy, naprimer,  k spryatannomu fajlu ili
fajlu tol'ko dlya chteniya.  Razlichnye atributy ob®yasneny v [5.2.6].
Rasshirennyj FCB na 7  bajtov  dlinnee,  prichem eti 7 bajtov pred-
shetsvuyut obychnomu bloku.  Pervyj bajt raven FF, chto ukazyvaet  na
special'nyj status. Za nim sleduyut 5 bajtov ASCII 0, a zatem bajt
atributov.  Pri otkrytii fajla s ispol'zovaniem rasshirennogo  FCB
DS:DX dolzhny ukazyvat' na pervyj iz dopolnitel'nyh semi bajtov, a
ne  na imya nakopitelya, kak dlya obychnogo FCB.  Vot obychnaya  forma,
gde 2 - znachenie bajta atributov, a 1 - ukazyvaet na nakopitel':

FCB     DB     0FFH, 5 DUP(0),2,1,'FILENAMEEXT',25 DUP(0)

Metod deskriptora fajla:
   |tot metod trebuet men'shej podgotovki  chem metod FCB. Dlya nego
Vy dolzhny tol'ko sozdat' stroku, ukazyvayushchuyu put' k fajlu,  takuyu
kak v standartnyh komandah DOS. Naprimer B:COMPILE\UTILITY\PASCAL
ukazyvaet na fajl PASCAL v podkataloge UTILITY. Stroka ogranichena
dlinoj v 63 simvola, vklyuchaya imya  nakopitelya.  Pri otkrytii fajla
(s  ispol'zovaniem  funkcii 3DH preryvaniya 21H -  sm.   [5.3.3]),
DS:DX dolzhny ukazyvat' na pervyj bajt etoj stroki. Sistema vypol-
nyaet  vsyu  rabotu po analizu stroki i nahozhdeniyu  fajla, a  posle
togo kak fajl otkryt ona  vozvrashchaet  16-bitnyj identifikacionnyj
nomer fajla v AX. Ego nazyvayut nomerom fajla i on ispol'zuetsya vo
vseh posleduyushchih operaciyah s etim fajlom.

Bufera dannyh:
   Programma dolzhna ukazat' mesto v pamyati, kuda dolzhny pomeshchat'-
sya  prinimaemye dannye ili otkuda dolzhny brat'sya vyvodimye.   |to
prostranstvo v pamyati mozhet byt' vremennym buferom, kotoryj budet
ispol'zovat'sya dannymi kak promezhutochnaya stanciya.  Ili eto prost-
ranstvo mozhet byt' imenno tem mestom,  gde dannye real'no obraba-
tyvayutsya.  Obychno vremennyj bufer ustanavlivaetsya razmerom v odnu
zapis' i byvaet udobno  opisat'  ego  kak  strokovuyu peremennuyu v
segmente  dannyh,  kak eto sdelano v nizheprivedennom primere.   S
drugoj storony, bol'shie rabochie  oblasti  dannyh dolzhny rasprede-
lyat'sya  s  pomoshch'yu metodov raspredeleniya pamyati,  predostavlyaemyh
operacionnoj sistemoj [1.3.1].   Ved' sozdanie, naprimer, oblasti
dannyh  razmerom v 10000 bajt v segmente dannyh sdelaet programmu
na diske na 10000 bajt dlinnee, chto sovershenno nenuzhno.

   Bufer  ispol'zuemyj  metodom FCB dostupa k  fajlam  nazyvaetsya
oblast'yu obmena s diskom ili DTA. Na etot bufer ukazyvaet slovnyj
ukazatel', kotoryj hranitsya operacionnoj sistemoj i kotoryj mozhet
byt' izmenen  Vashej  programmoj.  V  firmennoj  dokumentacii etot
ukazatel' na DTA chasto sam nazyvayut DTA. Poskol'ku ukazano tol'ko
nachalo bufera, to nichto ne meshaet dannym zanyat' oblast' prilegayu-
shchuyu  k DTA, poetomu Vy sami dolzhny sledit', chtoby etogo ne  proi-
zoshlo. Ukazatel' na DTA  ustanavlivaetsya special'noj funkciej DOS
i  posle togo kak on ustanovlen vse funkcii chteniya/zapisi avtoma-
ticheski obrashchayutsya k nemu.   |to  oznachaet,  chto  sami funkcii ne
dolzhny soderzhat' adres vremennogo bufera.


   Kogda DTA sovpadaet s oblast'yu dannyh, v kotoroj obrabatyvayut-
sya dannye, to neobhodimo postoyanno menyat' DTA, s tem chtoby fajlo-
vye operacii mogli poluchat' dostup k razlichnym fragmentam dannyh.
Pri prostoj operacii  posledovatel'nogo  chteniya  ili pri operacii
chteniya odnogo bloka s pryamym dostupom sistema avtomaticheski pome-
shchaet v DTA odnu zapis' za drugoj.  Neobhodimo otvesti prostranst-
vo,  dostatochnoe  dlya chisla zapisej,  kotorye  budut  zatrebovany
programmoj. DTA ne mozhet  imet'  razmery  bol'she  odnogo segmenta
(64K).
   Dlya ustanovki ukazatelya na DTA ispol'zujte funkciyu 1AH  prery-
vaniya 21H. DS:DX  dolzhny  ukazyvat'  na  pervyj bajt DTA, a zatem
nado vypolnit' funkciyu. |to vse chto nuzhno. Vot primer:

;---v segmente dannyh
DTA      256 DUP (?)

;---ustanovka DTA
   LEA  DX,DTA      ;DS:DX ukazyvayut na DTA
   MOV  AH,1AH      ;funkciya ustanovki DTA
   INT  21H         ;ustanovka DTA

   Funkciya 2FH preryvaniya 21H soobshchaet tekushchuyu ustanovku ukazate-
lya DTA.  U nee net vhodnyh registrov. Pri vozvrate ES:BX soderzhat
segment i smeshchenie DTA.
   Prefiks  programmnogo  segmenta  [1.3.0]  obespechivaet  kazhduyu
programmu 128-bajtnym  vstroennym  DTA, nachinaya so smeshcheniya 80H i
do 9FH.  Vy mozhete ispol'zovat' ego pri nehvatke pamyati. Pervona-
chal'no ukazatel' na DTA  ukazyvaet  imenno na etot bufer, poetomu
esli  Vy budete ispol'zovat' ego, to net nuzhdy ustanavlivat' uka-
zatel'.  |tot bufer po umolchaniyu  osobenno  udobno ispol'zovat' s
COM  fajlami,  gde DS ukazyvaet na nachalo  prefiksa  programmnogo
segmenta. Dlya fajlov EXE mozhet potrebovat'sya nebol'shoj dobavochnyj
kod, chtoby ispol'zovat' DTA po umolchaniyu.  Otmetim, chto dlya opre-
deleniya tekushchej ustanovki ukazatelya na DTA Vy dolzhny ispol'zovat'
funkciyu  2FH preryvaniya 21H.  U nee net vhodnyh registrov, a  pri
vyhode ES:BX ukazyvayut na DTA.
   Ukazatel' na DTA ne  ispol'zuetsya  pri dostupe k fajlu metodom
deskriptora fajla. Funkcii chteniya ili zapisi dannyh vsegda soder-
zhat adres, po kotoromu raspolozhen bufer dannyh.  Celikom na Vashej
sovesti  lezhit  opredelenie togo, budut  li  dannye  peredavat'sya
cherez vremennyj bufer  ili  neposredstvenno  v  to mesto, gde oni
budut ispol'zovat'sya.




   Pri  zapuske mnogie programmy pozvolyayut pol'zovatelyu pomestit'
dobavlchnuyu informaciyu v komandnoj  stroke, obychno ukazyvayushchuyu imya
fajla, s kotorym programma budet rabotat'. |ta informaciya zapisy-
vaetsya v 128-bajtnuyu  oblast',  nachinayushchuyusya  so  smeshcheniya  80H v
prefikse  programmnogo segmenta [1.3.0].  (|ta zhe oblast' ispol'-
zuetsya kak DTA po umolchaniyu,  kak  obsuzhdalos' v [5.3.5].) Pervyj
bajt soderzhit dlinu stroki, a zatem idet sama stroka.


   Dlya  programm, ispol'zuyushchih metod deskriptora fajla dlya raboty
s fajlami, imya fajla, vvodimoe  v  komandnoj stroke, dolzhno imet'
adekvatnuyu formu. Trebuetsya, chtoby pol'zovatel' programmy ispol'-
zoval standartnyj protokol MS DOS dlya stroki puti.  S drugoj sto-
rony, upravlyayushchij blok fajla trebuet, chtoby stroka vida 'A:ACCT.-
BAK' byla preobrazovana k  vidu  1,'ACCT     BAK'.  MS  DOS imeet
special'nuyu  funkciyu, kotoraya vypolnyaet takoe preobrazovanie  nad
pervoj porciej informacii,  sleduyushchej  za  imenem programmy v ko-
mandnoj  stroke.  |ta procedura nazyvaetsya razborom stroki  (par-
sing).

   Srednij uroven'.

   Imya fajla dolzhno byt' pervoj  informaciej, sleduyushchej za imenem
zagruzhaemoj programmy. Ono dolzhno byt' otdeleno ot imeni program-
my odnim iz sleduyushchih simvolov : .  ; , = + tabulyaciej ili probe-
lom. Konec imeni fajla dolzhen byt' ukazan odnim iz simvolov : . ;
, = + \ < > | / " [ ] tabulyaciej, probelom ili odnim iz upravlyayu-
shchih simvolov (kody ASCII ot 1 do 31).
   Funkciya  29H  preryvaniya 21H proizvodit  razbor  imeni  fajla.
DS:SI  dolzhny ukazyvat' na smeshchenie 81H v PSP.  Pomnite, chto  pri
zagruzke  programmy  kak DS, tak i ES ukazyvayut  na  nachalo  PSP.
ES:DI dolzhny ukazyvat' na  oblast'  pamyati, kotoraya budet sluzhit'
upravlyayushchim blokom dlya novogo fajla. Ustanovka bitov v AL oprede-
lyaet kak budet vypolnyat'sya  razborka.  Imeyut znachenie tol'ko bity
0-3:

   bit 0   1 = nachal'nyj ogranichitel' ignoriruetsya
       1   1 = bajt, identificiruyushchij nakopitel', ustanavlivaetsya
               v FCB, tol'ko esli on ukazan v komandnoj stroke
       2   1 = imya fajla v FCB menyaetsya tol'ko esli komandnaya
               stroka soderzhit imya fajla
       3   1 = rasshirenie fajla v FCB menyaetsya tol'ko esli koman-
               naya stroka soderzhit rasshirenie fajla

Posle  togo kak eta informaciya ustanovlena, programma mozhet vyzy-
vat' funkciyu.  Esli v komandnoj  stroke  ne ukazan nakopitel', to
beretsya  nakopitel'  po umolchaniyu.  Esli  otsutstvuet  rasshirenie
fajla, to predpolagaetsya, chto ono  probel'noe (ASCII 32).  Esli v
imeni fajla ukazana zvezdochka, to ona zamenyaetsya na nuzhnoe  chislo
voprositel'nyh znakov v pole  imeni  fajla FCB.  AL vozvrashchaet 1,
esli  imya fajla soderzhit * ili ? i FF, esli ukazan nevernyj nako-
pitel'.
   Pri vozvrate DS:SI ukazyvayut  na  pervyj  simvol, sleduyushchij za
imenem  fajla,  kotoroe nachinaetsya so smeshcheniya  81H.   Dal'nejshaya
informaciya, soderzhashchayasya  v  komandnoj  stroke dolzhna rasshifrovy-
vat'sya  Vashej programmoj.  ES:DI ukazyvayut na pervyj  bajt  vnov'
sformirovannogo FCB.  Esli  v  FCB  ne  sozdano dopustimogo imeni
fajla, to soderzhimoe ES:[DI]+1 ravno probelu. Vot primer, kotoryj
pomeshchaet kod v oblast' FCB v PSP, nachinaya so smeshcheniya 5CH:


;---razbiraem komandnuyu stroku, sozdavaya FCB so smeshcheniem 5CH
;---v PSP
   MOV  AH,29H          ;
   MOV  SI,81H          ;
   MOV  DI,5CH          ;
   MOV  AL,1111B        ;
   INT  21H             ;
   MOV  AL,ES:[DI]+1    ;
   CMP  AL,32           ;
   JE   ERROR_ROUTINE   ;




   Imeyutsya dva osnovnyh metoda dostupa k fajlu - posledovatel'nyj
i pryamoj. Hotya v vychislitel'noj  literature chasto ispol'zuyut ter-
miny  "posledovatel'nyj"  fajl i fajl "pryamogo dostupa", sami  po
sebe fajly hranyatsya na diske odinakovo:  kak nepreryvnaya posledo-
vatel'nost'  bajtov.  Ni v kataloge ni v kakom-libo drugom  meste
net indikatora, ukazyvayushchego, chto dannyj fajl yavlyaetsya posledova-
tel'nym ili fajlom pryamogo dostupa.  Real'no eti dva tipa  fajlov
razlichayutsya po  raspolozheniyu  dannyh  v nih i po metodu dostupa k
nim. K lyubomu fajlu pryamogo dostupa mozhno poluchit' posledovatel'-
nyj dostup, a k lyubomu  posledovatel'nomu  fajlu - pryamoj dostup,
hotya redko imeyutsya prichiny delat' eto, osobenno vo vtorom sluchae.
   Posledovatel'nye  fajly pomeshchayut elementy dannyh odin za  dru-
gim, nezavisimo ot ih dliny,  razdelyaya  eti elementy paroj simvo-
lov,  snachala  vozvratom  karetki (ASCII 13), a  zatem  perevodom
stroki (ASCII  10).   YAzyki  vysokogo  urovnya,  takie kak Bejsik,
vstavlyayut  eti simvoly avtomaticheski, v to vremya kak programmy na
assemblere dolzhny sami  zabotit'sya  o vstavke etih simvolov posle
zapisi kazhdoj peremennoj v fajl.  V posledovatel'nyh fajlah mogut
hranit'sya kak chisla, tak i stroki. Stroki trebuyut po odnomu bajtu
na kazhdyj simvol stroki. CHisla po soglasheniyu zapisyvayutsya v stro-
kovom vide, hotya oni  mogut  pisat'sya  i  v  chislovom vide. Takim
obrazom  Bejsik zapisyvaet znachenie "128" v vide stroki  iz  treh
cifr, hotya programma  na  assemblere  mozhet  zapisat' eto chislo v
vide dvuhbajtnogo celogo ili dazhe odnobajtnogo koda - vse oprede-
lyaetsya tem, chto pri povtornom chtenii fajla programma dolzhna poni-
mat' ispol'zuemyj format.  Dlya somestimosti rekomenduetsya zapisy-
vat' chisla v vide strok.
   Neobyazatel'no, chtoby kazhdoe  chislo  stroki bylo otdeleno paroj
vozvrat karetki/perevod stroki, odnako esli eta para opushchena,  to
programma dolzhna obespechit' sposob otdeleniya dannyh. Naprimer, 10
celyh chisel mogut byt' zapisany kak 20-bajtnyj element dannyh.  S
drugoj storony, ochen' bol'shie elementy dannyh, takie kak paragra-
fy  teksta,  mogut byt' razdeleny na neskol'ko  elementov  dannyh
(standartnyj tekstovyj fajl predstavlyaet iz sebya dokument, razbi-
tyj  na  stroki udobnogo  razmera,  zapisannye  posledovatel'no).
Poskol'ku elementy dannyh imeyut  peremennuyu  dlinu, to nevozmozhno
uznat'  gde v fajle raspolozhen opredelennyj element.  Poetomu dlya
togo chtoby najti  nuzhnyj  element  programma  dolzhna chitat' fajl,
nachinaya s nachala i  otschityvaya  nuzhnoe  chislo  par vozvrat karet-
ki/perevod stroki.  Po etoj prichine fajly takogo formata nazyvayut
posledovatel'nymi.  Kak pravilo  s diska v pamyat' peredaetsya ves'
takoj fajl.
   Fajly  pryamogo dostupa zaranee otvodyat fiksirovannoe mesto pod
kazhdyj element dannyh.  Esli  kakoj-to element dannyh ne zanimaet
vse  otvedennoe  prostranstvo, to ostatok zapolnyaetsya  probelami.
Esli kazhdyj element zanimaet 10  bajtov,  to legko mozhno prosmot-
ret'  srazu 50-j element, poskol'ku mozhno vychislit' chto on  nachi-
naetsya s 491-go bajta fajla (t.e.  s bajta #490, poskol'ku otschet
nachinaetsya  s 0).  Kak pravilo svyazannyj nabor elementov  gruppi-
ruetsya v zapis'. Kazhdaya zapis'  soderzhit neskol'ko polej, kotorye
sozdayut  nabor  nomerov bajtov, nachinaya s kotoryh pishutsya  dannye
elementy.  Naprimer, zapis' mozhet imet' polya vozrast, ves i rost.


Sootvetstvuyushchie polya mogut zanimat' 2, 3 i 5 bajtov.  Vmeste  oni
obrazuyut zapis' dlinoj v 10  bajtov.   Fajl pryamogo dostupa mozhet
sostoyat'  iz tysyach takih zapisej.  Kazhdaya zapis'  sleduet  nepos-
redstvenno za predshestvuyushchej bez  vsyakih ogranichitelej, takih kak
pary  vozvrat  karetki/perevod stroki, ispol'zuemye v  posledova-
tel'nyh fajlah.  Pri etom zapisi mogut pisat'sya v lyubom poryadke i
mozhno  zapisat'  zapis' 74, hotya zapis' 73 eshche ne  byla  zapisana
(pri etom zapisi 73  otvedeno  diskovoe  prostranstvo i ona budet
soderzhat'  te dannye, kotorye sluchajno okazalis' v tom sektore, v
kotorom otvedeno mesto dlya etoj zapisi).  V otlichii ot posledova-
tel'nyh fajlov fajly pryamogo dostupa ostayutsya na diske.  V pamyati
prisutstvuyut tol'ko opredelennye zapisi, s kotorymi idet rabota v
dannyj moment vremeni.
   Kogda  dlya  pryamogo dostupa k fajlu  ispol'zuetsya  upravlyayushchij
blok fajla, to sisteme soobshchaetsya razmer zapisi fajla (vse zapisi
dannogo fajla dolzhny imet' odinakovuyu dlinu). |to pozvolyaet prog-
ramme zaprosit' lyubuyu zapis' po  nomeru,  a MS DOS tochno vychislit
gde eta zapis' raspolozhena na diske. Pri rabote s fajlami pryamogo
dostupa metodom deskriptora fajla programma dolzhna sama vychislyat'
polozhenie trebuemoj zapisi.
   Sistema hranit fajlovyj ukazatel' dlya kazhdogo bufera fajla. On
ukazyvaet na n-nyj bajt fajla, opredelyaya mesto v fajle, s kotoro-
go  budet  nachinat'sya sleduyushchaya operaciya chteniya ili zapisi.   Pri
posledovatel'noj operacii perezapisi  fajlovyj ukazatel' pervona-
chal'no ustanavlivaetsya na nachalo fajla i postoyanno sdvigaetsya  po
mere togo, kak vse  novye  i  novye  dannye  zapisyvayutsya v fajl.
Kogda  dannye dobavlyayutsya k posledovatel'nomu fajlu, to  fajlovyj
ukazatel' pervonachal'no ustanavlivaetsya na konec fajla.  Pri dos-
tupe  k  odnoj zapisi v fajle pryamogo  dostupa  polozhenie  zapisi
vychislyaetsya v vide smeshcheniya otnositel'no nachala fajla i ukazatel'
ustanavlivaetsya  ravnym  etomu znacheniyu; zatem nuzhnaya zapis'  chi-
taetsya ili pishetsya. Obychno za fajlovym ukazatelem sledit sistema,
odnako programma mozhet sama upravlyat' im i manipulirovat'  ukaza-
telem dlya svoih special'nyh nuzhd.
   Edinstvennym primerom nizkogo urovnya v dannom razdele yavlyaetsya
chtenie/zapis'  odnogo  sektora.  CHtenie ili zapis'  celyh  fajlov
sostoit v  posledovatel'nosti  takih  chtenij  ili  zapisej odnogo
sektora,  programmiruya  mikroshemu kontrollera  NGMD  zanovo  dlya
kazhdogo sektora.  Polnomasshtabnye  fajlovye operacii ochen' slozhny
na  etom  urovne, chto sleduet hotya by iz bol'shih  razmerov  fajla
COMMAND.COM. Odnako, izuchiv obsuzhdenie operacij nizkogo urovnya, a
takzhe imeya informaciyu o tablice razmeshcheniya fajlov [5.1.1] i  dis-
kovyh katalogah [5.2.1] Vy  mozhete  predstavit' kak rabotaet dis-
kovaya operacionnaya sistema.




   Mikroshema kontrollera NGMD 765  firmy NEC upravlyaet motorom i
golovkami  nakopitelya na disketah i obrabatyvaet  potoki  dannyh,
napravlyaemye v ili iz diskovyh sektorov.   Odin kontroller, usta-
novlennyj na plate adaptora diskov, mozhet obsluzhivat' do  chetyreh


NGMD. Za isklyucheniem sluchaev, svyazannyh s zashchitoj ot kopirovaniya,
programmistam ne prihoditsya programmirovat' mikroshemu kontrolle-
ra NGMD pryamo. Procedury raboty  s diskami, predostavlyaemye DOS i
BIOS effektivny i udobny, krome togo, ochen' riskovano pisat' svoi
sobstvennye  procedury,  poskol'ku  oshibki  v nih mogut razrushit'
diskovyj katalog ili tablicu razmeshcheniya fajlov, chto vyzovet  pol-
noe razrushenie informacii na diske.
   Nizhesleduyushchee  obsuzhdenie  sluzhit  celi  dat' Vam tol'ko obshchee
predstavlenie.   Listing  ROM-BIOS, privedennyj v  konce  kazhdogo
tehnicheskogo rukovodstva po MS DOS, soderzhit kod tshchatel'no razra-
botannyh  procedur  dlya  formatirovaniya disket,  chteniya i  zapisi
sektorov, a takzhe sbrosa i  polucheniya  statusa nakopitelej. Posle
togo, kak Vy usvoite privedennyj zdes' material, izuchite procedu-
ry ROM-BIOS dlya prodolzheniya Vashego obrazovaniya v oblasti operacij
s diskami na nizkom urovne. Vam potrebuetsya takzhe dokumentaciya po
mikrosheme kontrollera NGMD 8272A firmy Intel, kotoraya analogichna
mikrosheme firmy NEC.  V dannoj dokumentacii perechisleny preryva-
niya, generiruemye kontrollerom NGMD,  v to vremya kak v dokumenta-
cii  po  IBM PC etogo spiska net.  Informaciya o mikrosheme  8272A
mozhet byt' najdena vo  vtorom  tome  Spravochnika  po  komponentam
mikrosistem (Microsystem Components Handbook).
   Kontroller NGMD mozhet vypolnyat' 15 operacij, iz kotoryh  zdes'
budut obsuzhdat'sya tol'ko tri: operacii poiska i chteniya ili zapisi
odnogo  sektora.   Ponimanie togo kak oni rabotayut  pozvolit  Vam
vypolnit' lyubuyu iz ostavshihsya dvenadcati,  pri uslovii, chto u Vas
budet  vysheupomyanutaya informaciya.  CHtenie fajla sostoit v  poiske
ego v  kataloge  [5.2.1],  opredelenii  ego  polozheniya na diske s
pomoshch'yu tablicy razmeshcheniya fajlov [5.1.1] i zatem nabore operacij
chteniya odnogo sektora. |ta procedura vklyuchaet 6 shagov:

1. Vklyuchenie motora i korotkoe ozhidanie, poka on naberet oboroty.
2. Vypolnenie operacii poiska i ozhidanie preryvaniya, ukazyvayushchego
na zavershenie etoj operacii.
3. Inicializaciya mikroshemy DMA dlya peresylki dannyh v pamyat'.
4. Posylka komandy chteniya kontrolleru NGMD i ozhidanie preryvaniya,
ukazyvayushchego, chto peresylka dannyh zavershena.
5. Poluchenie informacii o statuse kontrollera NGMD.
6. Vyklyuchenie motora.

   Kontroller  NGMD  rabotaet cherez tri porta  vvoda/vyvoda.   Na
samom dele mikroshema imeet  bol'she,  chem tri registra, no dostup
k  bol'shinstvu  iz nih osushchestvlyaetsya cherez odin port.   |ti  tri
porta takie:

   3F2H          registr cifrovogo vyvoda
   3F4H          registr statusa
   3F5H          registr dannyh

   Pervyj shag sostoit v  dostupe  k  registru  cifrovogo  vyvoda.


Znachenie ego bitov sleduyushchee:

   bity 1-0     vybor nakopitelya, gde 00 = A
                                      01 = B
                                      10 = C
                                      11 = D
          2     0 = sbros kontrollera NGMD
          3     1 = razreshenie preryvaniya FDC i dostupa DMA
        7-4     1 = vklyuchenie motora nakopitelya D-A (bit 4 = A)

|to registr tol'ko dlya zapisi, poetomu neobhodimo zabotit'sya  obo
vseh ego bitah. V nizheprivedennom primere ispol'zuetsya nakopitel'
A, poetomu cepochka bitov dolzhna vyglyadet' 00011100.  Takaya  usta-
novka bitov vybiraet nakopitel' A, sohranyaet ustanovlennym bit 2,
razreshayushchij rabotu s NGMD i vklyuchaet motor nakopitelya A. Ne sbra-
syvajte bit 2 v nol', tak kak v etom sluchae Vam pridetsya proizvo-
dit'  perekalibrovku  nakopitelya,  dejstvie,  kotoroe  neobhodimo
ochen' redko.
   "Perekalibrovka" nakopitelya podrazumevaet  vozvrat ego golovki
na nulevuyu dorozhku.  |ta operaciya osushchestvlyaetsya posylkoj prostoj
posledovatel'nosti komand kontrolleru  NGMD.  Kontroller NGMD up-
ravlyaet tekushchej poziciej golovki, za schet zapominaniya vseh  izme-
nenij pozicii golovki posle  ee  nachal'noj  ustanovki  na nulevuyu
dorozhku.   Kogda kontroller NGMD sbrasyvaetsya, za schet  izmeneniya
bita 2 registra  cifrovogo  vyvoda,  to  znachenie tekushchej pozicii
golovki  ustanavlivaetsya  v nol', nezavisimo ot  togo,  na  kakoj
dorozhke nahoditsya golovka na  samom  dele, chto delaet neobhodimym
perekalibrovku. Obychno sbros kontrollera NGMD proizvoditsya tol'ko
v sluchae takoj ser'eznoj oshibki  nakopitelya,  posle kotoroj neiz-
vestno tekushchee sostoyanie kontrollera NGMD i nakopitelya.
   Otmetim,  chto  vybor nakopitelya i vklyuchenie ego  motora -  eto
otdel'nye dejstviya. Kontroller  NGMD  mozhet imet' dostup tol'ko k
odnomu  nakopitelyu v dannyj moment vremeni, no motry  mogut  byt'
vklyucheny u neskol'kih.  Motory  mogut  ostavat'sya vklyuchennymi eshche
neskol'ko  sekund  posle  zaversheniya obmena  dannymi, v  ozhidanii
sleduyushchego dostupa k nakopitelyu.  Takaya strategiya pozvolyaet izbe-
zhat'  poteri  vremeni  na povtornoe ozhidanie poka  motor  naberet
skorost'.  Naprotiv, motor nel'zya ostavlyat' postoyanno vklyuchennym,
tak kak eto privedet k prezhdevremennomu iznosu disket.
   Rabota  mikroshemy  kontrollera NGMD razdelyaetsya na tri  fazy:
komandnaya faza, faza vypolneniya  i  faza  rezul'tata. V komandnoj
faze odin ili bolee bajtov posylayutsya v registr dannyh.  Posledo-
vatel'nost' bajtov strogo fiksirovana i ona menyaetsya ot komandy k
komande. Zatem kontroller NGMD vypolnyaet komandu i v eto vremya on
nahoditsya v faze vypolneniya.  Nakonec,  vo vremya fazy rezul'tata,
ryad bajtov statusa schityvayutsya iz registra dannyh.  Pri etom obya-
zatel'no, chtoby ne bylo oshibki v chisle peredavaemyh ili schityvae-
myh dannyh v registr dannyh v fazah komandnoj i rezul'tata.
   CHislo  bajtov  komandy i rezul'tata menyaetsya v zavisimosti  ot
vypolnyaemoj kontrollerom  diskovoj  operacii. V tehnicheskom ruko-
vodstve po IBM PC privedeny dannye dlya vseh 15 operacij.   Pervyj
bajt komandy yavlyaetsya  kodom,  opredelyayushchim  trebuemuyu  operaciyu.
Nomer  koda soderzhitsya v mladshih 5-ti bitah bajta  i v  nekotoryh


sluchayah v starshih treh bitah  zakodirovana dobavochnaya informaciya.
V  bol'shinstve sluchaev vtoroj bajt komandy soderzhit nomer nakopi-
telya (0-3) v mladshih dvuh bitah i  nomer golovki (0 ili 1) v bite
2, vse ostal'nye bity ignoriruyutsya kontrollerom NGMD.  Pri opera-
cii poiska trebuetsya  dopolnitel'no eshche tol'ko odin bajt, v koto-
rom  dolzhen soderzhat'sya nomer novoj dorozhki.  CHtenie  ili  zapis'
sektora trebuet  semi  dopolnitel'nyh  komandnyh  bajtov, kotorye
identichny v etih dvuh sluchayah. Bajty s tret'ego po pyatyj soderzhat
tekushchij nomer dorozhki,  nomer  golovki  i  nomer sektora. Za nimi
sleduyut  chetyre bajta, soderzhashchie tehnicheskuyu informaciyu, neobho-
dimuyu dlya kontrollera NGMD.
   Pervyj bajt etoj  tehnicheskoj  informacii  otnositsya  k  chislu
bajtov v sektore, kotoroe kodiruetsya kak 0 dlya 128, 1 dlya 256,  2
dlya 512 i 3 dlya 1024. Konechno  diskety,  sozdannye v MS DOS imeyut
sektora razmerom 512 bajt. Zatem idut dannye konca dorozhki (EOT),
kotorye dayut maksimal'nyj nomer sektora  dlya cilindra; eto znache-
nie  ravno 9 dlya disket emkost'yu 360K.  Nakonec, idet bajt dayushchij
dlinu sdviga (GPL, ravnyj 2AH) i dlinu  dannyh (DTL, ravnyj FFH).
Tehnicheskoe  rukovodstvo  po IBM PC soderzhit  tablicu, v  kotoroj
ob®yasnyayutsya drugie vhozhnye  parametry,  naprimer  te, kotorye is-
pol'zuyutsya pri formatirovanii diska.  MS DOS hranit chetyre tehni-
cheskih parametra v  pamyati,  v  special'noj  tablice  parametrov,
nazyvaemoj bazoj diska (disk base).  Vektor preryvaniya 1EH ukazy-
vaet na etu tablicu.  CHetyre  znacheniya  hranyatsya v tom poryadke, v
kotorom  oni  dolzhny byt' peredany kontrolleru NGMD,  nachinaya  so
smeshcheniya 3. V sleduyushchej tablice pokazana komandnaya posledovatel'-
nost' dlya treh operacij, ispol'zuemyh v nizheprivedennom  primere.
V cepochkah bitov chereh X  oboznacheny bity, znachenie kotoryh nesu-
shchestvenno,  cherez H - nomer golovki, a cherez DD - nomer nakopite-
lya.

   Operaciya   # bajta   Funkciya           Ustanovka dlya golovki 0
                                           dorozhki 15, sektora 1

   Poisk         1      nomer koda 00001111           1FH
                 2      golovka i nakopitel'          00H
                        XXXXXHDD

   CHtenie        1      nomer koda 01100110           66H
   sektora       2      golovka i nakopitel'          00H
                        XXXXXHDD
                 3      nomer dorozhki                 0FH
                 4      nomer golovki                 00H
                 5      nomer sektora                 01H
                 6      bajtov v sektore              02H
                 7      konec dorozhki                 09H
                 8      dlina sdviga                  1AH
                 9      dlina dannyh                  FFH

   Zapis'        1      nomer koda 01000101           45H
   sektora     2-9      te zhe, chto i dlya chteniya sektora


   Vy  dolzhny byt' uvereny, chto kontroller NGMD gotov prezhde  chem
Vy poshlete ili prochitaete bajt  iz  registra  dannyh.  Bity 7 i 6
registra statusa predostavlyayut etu informaciyu. Vot znachenie bitov
etogo registra:

bity 3-0    1 = nakopitel' D-A v rezhime poiska
       4    1 = kontroller NGMD vypolnyaet komandu chteniya/zapisi
       5    1 = kontroller NGMD ne v rezhime DMA
       6    1 = registr dannyh kontroller NGMD gotov k priemu
                dannyh
            0 = gotov k posylke dannyh
       7    1 = kontroller NGMD gotov k posylke ili priemu dannyh

Pered nachalom  diskovyh  operacij  neploho  proverit',  chto bit 6
raven  nulyu, indiciruya chto kontroller NGMD ozhidaet komandu.  Esli
on ozhidaet posylki dannyh, to proizoshla oshibka. Kogda bajt dannyh
posylaetsya v registr dannyh, to bit 7 registra statusa stanovitsya
ravnym nulyu; prodolzhajte chtenie registra  do teh por, poka bit ne
izmenitsya obratno na 1, a zatem posylajte sleduyushchij bajt komandy.
Analogichno, proveryajte etot bit statusa  pered chteniem bajta sta-
tusa  v faze rezul'tata.  Nizheprivedennyj primer konchaetsya  dvumya
procedurami, kotorye vypolnyayut eti funkcii.
   Kogda operaciya poiska zavershena, to kontroller NGMD iniciiruet
preryvanie 6, preryvanie ot NGMD. Hotya tak zhe prosto mozhno uznat'
ob okonchanii operacii poiska  proveryaya registr statusa, v primere
eto delaetsya za schet obrabotki preryvaniya.  Kogda proishodit pre-
ryvanie, to obrabotchik preryvaniya  BIOS ustanavlivaet bit 7 bajta
statusa  poiska v oblasti dannyh BIOS, raspolozhennogo  po  adresu
0040:003E. |to edinstvennyj rezul'tat obrabotki preryvaniya. Mozhno
proveryat' etot bajt do teh por, poka bit 7 ne budet ustanovlen, a
zatem perehodit' k sleduyushchemu shagu operacii chteniya sektora.
   Sleduyushchij shag sostoit v  inicializacii mikrosheiy pryamogo dos-
tupa  k  pamyati 8237.  |ta mikroshema zanimaetsya  obmenom  dannyh
mezhdu  periferijnymi  ustrojstvami  i  pamyat'yu,  rabotoj, kotoroj
mozhet zanimat'sya takzhe processor.  Na samom dele, v PCjr, gde net
mikroshemy DMA, kontroller NGMD  posylaet  dannye pryamo v proces-
sor,  kotoryj  v svoyu ochered' peresylaet ih v  pamyat'.   Taktovaya
chastota processora  adekvatna  etoj  zadache, odnako pri peresylke
dannyh  vse  preryvaniya  dolzhny byt' zapreshcheny, s  tem  chtoby  ne
proishodilo poteri dannyh. |to  oznachaet, chto v PCjr pri peredache
dannyh vvod s klaviatury ili iz modema zapreshchen.  Preryvaniya taj-
mera takzhe  ignoriruyutsya,  odnako  vposledstvii  schetchik  vremeni
sutok  obnovlyaetsya special'noj proceduroj, ispol'zuyushchej  kanal  1
mikroshemy tajmera  8253  dlya  podscheta  impul'sov,  proshedshih za
vremya diskovyh operacij.  Vse ostal'nye modeli IBM PC imeyut  mik-
roshemu DMA, poetomu processor svoboden pri peredache dannyh.
   IBM PC i XT ispol'zuyut 4-hkanal'nuyu mikroshemu DMA 8237. Kanal
0  prednaznachen dlya "osvezheniya" pamyati (memory refresh); on  pos-
toyanno vosstanavlivaet zaryad  yacheek  operativnoj pamyati.  Esli Vy
budete  rabotat' po etomu kanalu, to eto privedet skoree vsego  k
krahu mashiny. Kanal 2  prednaznachen  dlya diskovyh operacij, a dva
drugie kanala, s nomerami 1 i 3, dostupny (cherez raz®emy rasshire-
niya) dlya  dopolnitel'nogo  oborudovaniya.  K  sozhaleniyu, obmen pa-


myat'-pamyat' trebuet dvuh kanalov i odnim iz nih dolzhen byt' kanal
0, poetomu takoj obmen nedostupen na IBM PC i XT. Odnako AT imeet
7  kanalov  pryamogo dostupa k pamyati i DMA avtomaticheski  ispol'-
zuetsya instrukciyami MOVS,  sushchestvenno  uvelichivaya proizvoditel'-
nost'.
   Pered inicializaciej kanala programma dolzhna poslat' v mikros-
hemu kod, soobshchayushchij budet  li  proishodit'  chtenie  ili zapis' v
kontroller NGMD.  |tot odnobajtnyj kod raven 46H dlya chteniya i 4AH
- dlya zapisi. |tot kod dolzhen byt' poslan v kazhdyj iz dvuh portov
s adresami 0BH i 0CH.
   Kazhdyj  kanal mikroshemy 8237 ispol'zuet tri  registra.   Odin
16-bitnyj registr, registr  schetchika, soderzhit chislo peredavaemyh
bajtov  dannyh.  Ego velichina dolzhna byt' na edinicu men'she,  chem
trebuemoe chislo bajtov.   Dlya  kanala  2  dostup k etomu registru
osushchestvlyaetsya cherez port 05H; poshlite v nego dva  posledovatel'-
nyh bajta, prichem snachala mladshij bajt.

   Ostal'nye dva registra soderzhat adres bufera v pamyati, s koto-
rym  budet  proishodit' obmen dannymi.  |tot adres  zadaetsya  kak
20-bitnoe chislo, poetomu, naprimer,  adres 3000:ABCD zadaetsya kak
3ABCD.  Mladshie 16 bitov posylayutsya v registr adresa, kotoryj dlya
kanala 2 imeet adres porta 04H.  Snachala posylaetsya mladshij bajt.
Starshie  4  bita  idut v registr stranicy, kotoryj dlya  kanala  2
imeet adres porta 81H.  Kogda bajt posylaetsya po etomu adresu, to
imeyut  znachenie  tol'ko 4 mladshih bita.  Esli bufer  sozdaetsya  v
segmente dannyh, to Vam  nuzhno  slozhit'  znachenie  DS  i smeshchenie
bufera dlya polucheniya 20-bitnogo znacheniya. Slozhenie mozhet privesti
k perenosu v znachenie registra stranicy.  Naprimer, esli DS raven
1F00H,  a smeshchenie bufera - 2000H, to rezul'tiruyushchij adres  budet
raven 1F00 + 2000 = 21000H.
   Posle togo kak eti tri registra  ustanovleny, poshlite 2 v port
s adresom 0AH, chtoby razreshit' kanal 2.  |to ostavlyaet mikroshemu
DMA v sostoyanii ozhidaniya dannyh ot nakopitelya, a programma dolzhna
nemedlenno nachat' posylku komandnyh bajtov v kontroller NGMD. Vot
kratkij perechen' shagov pri programmirovanii mikroshemy 8237:

1. Poslat' kod chteniya ili zapisi.
2.  Vychislit' 20-bitnyj adres pamyati bufera, v kotoryj budut pos-
lany dannye, i zaslat' ego v registry adresa i stranicy kanala 2.
3.  Pomestit' znachenie chisla peredavaemyh  bajtov (minus 1) v re-
gistr schetchika kanala 2.
4. Razreshit' kanal.

   Posle posylki  komandnyh  bajtov,  snova ozhidajte preryvaniya i
obrashchajtes'  s  nim tak zhe, kak i posle operacii  poiska.   Zatem
prochitajte bajty statusa. Oni takovy:

   Operaciya    # bajta      Funkciya

   Poisk         net

   CHtenie         1        bajt statusa 0
                  2        bajt statusa 1


                  3        bajt statusa 2
                  4        nomer dorozhki
                  5        nomer golovki
                  6        nomer sektora
                  7        kod bajtov na sektor (0-3)

   Zapis'       1-7        to zhe, chto i dlya chteniya

Vot znacheniya bitov treh bajtov statusa:

Bajt statusa 0:
   bity 7-6   00 = normal'noe zavershenie
              01 = nachato vypolnenie, ne mozhet zavershit'sya
              10 = nevernaya komanda
              11 = nevypolneno, t.k. nakopitel' ne podklyuchen
          5   1 = vypolnyaetsya operaciya poiska
          4   1 = oshibka nakopitelya
          3   1 = nakopitel' ne gotov
          2   nomer vybrannoj golovki
        1-0   nomer vybrannogo nakopitelya

Bajt statusa 1:
   bit 7   1 = nomer zatrebovannogo sektora bol'she maksimuma
       6   ne ispol'zuetsya (vsegda 0)
       5   1 = oshibka peredachi dannyh
       4   1 = perepolnenie dannyh
       3   ne ispol'zuetsya (vsegda 0)
       2   1 = ne mozhet najti ili prochitat' sektor
       1   1 = ne mozhet zapisat' iz-za zashchity ot zapisi
       0   1 = otsutstvuet adresnaya metka pri formatizacii

Bajt statusa 2:
   bit 7   ne ispol'zuetsya (vsegda 0)
       6   1 = vstrechena adresnaya metka udalennyh dannyh
       5   1 = oshibka ciklicheskogo kontrolya chetnosti dannyh
       4   1 = problema s identifikaciej dorozhki
       3   1 = uslovie komandy skanirovaniya udovletvoreno
       2   1 = uslovie komandy skanirovaniya ne udovletvoreno
       1   1 = plohaya dorozhka
       0   1 = otsutstvuet adresnaya metka

   Kak Vy vidite bol'shaya chast' informacii  otnositsya k formatiro-
vaniyu diska, kotoroe nas v nastoyashchij moment ne interesuet. Odnako
imeetsya eshche chetvertyj  bajt  statusa,  kotoryj  soderzhit poleznuyu
informaciyu:

Bajt statusa 3:
   bit 7   1 = oshibka nakopitelya
       6   1 = disk zashchishchen ot zapisi
       5   1 = nakopitel' gotov
       4   1 = tekushchaya poziciya golovki izvestna
       3   1 = disketa dvuhstoronnyaya
       2   nomer vybrannoj golovki
     1-0   nomer vybrannogo nakopitelya


Vy mozhete poluchit' etot chetvertyj bajt statusa, poslav kontrolle-
ru NGMD komandu  "Opredeli  status  nakopitelya" (Sense Drive Sta-
tus).  Pervyj bajt etoj dvuhbajtnoj komandy eto chislo 4, a vtoroj
bajt soderzhit nomer nakopitelya  v  bitah 1 i 0, i nomer golovki v
bite  2.   Edinstvennym rezul'tatom etoj operacii  yavlyaetsya  bajt
statusa 3.  Otmetim, chto posle  kazhdoj diskovoj operacii, esli Vy
ispol'zuete  procedury DOS ili BIOS, rezul'tiruyushchie bajty statusa
pomeshchayutsya v oblast'  dannyh  BIOS,  nachinaya  s adresa 0040:0042.
Operacionnaya  sistema hranit takzhe bajt statusa diskety po adresu
0040:0041, znachenie bitov kotorogo sleduyushchee:

   Znachenie bita             Oshibka

        80H           net otveta na prisoedinenie nakopitelya
        40H           operaciya poiska neuspeshna
        20H           oshibka kontrollera NGMD
        10H           oshibka dannyh pri chtenii (oshibka CRC)
        09H           popytka pryamogo dostupa za granicu 64K
        08H           perepolnenie DMA
        04H           zatrebovannyj sektor ne najden
        02H           ne najdena adresnaya marka
        01H           poslana nevernaya komanda kontrolleru NGMD

   V zaklyuchenie privodim polnuyu  proceduru  chteniya diska, kotoraya
chitaet odin sektor dannyh s dorozhki 12, sektor 1, storona 0 nako-
pitelya A v 512-bajtnyj bufer v segmente dannyh.  Sem' bajtov sta-
tusa takzhe schityvayutsya v otvedennyj bufer. |ta procedura prednaz-
nachena dlya IBM PC i XT.  Vam neobhodimo vospol'zovat'sya tehniches-
kim  rukovodstvom po PCjr ili AT, esli Vy rabotaete na etih mashi-
nah.  Na AT nado izmenit'  cikly  zaderzhki,  chtoby uchest' bol'shuyu
skorost'  processora, i ne zabyvat' dobavlyat' operator JMP  SHORT
$+2 mezhdu posledovatel'nymi  komandami OUT, otnosyashchimisya k odnomu
i  tomu zhe portu.  Rabota s fiksirovannym  diskom  osushchestvlyaetsya
analagichno, poetomu Vy mozhete  perenesti izuchennye Vami koncepcii
na drugie situacii.

;---v segmente dannyh
BUFFER         DB 512 DUP(?)
STATUS_BUFFER  DB 7 DUP(?)

SECTOR_READ    PROC    ;nachalo procedury chteniya odnogo sektora
;---vklyuchenie motora
   STI              ;preryvaniya dolzhny byt' razresheny
   MOV  DX,3F2H     ;adres registra cifrovogo vyvoda
   MOV  AL,28       ;ustanavlivaem bity 2, 3 i 4
   OUT  DX,AL       ;posylaem komandu
;---ozhidaem poka motor naberet skorost' (okolo 1/2 sek.)
   MOV  CX,3500     ;schetchik cikla zaderzhki (dlya IBM PC i XT)
MOTOR_DELAY:  LOOP MOTOR_DELAY  ;ozhidaem 1/2 sekundy
;---vypolnyaem operaciyu poiska
   MOV  AH,15       ;nomer koda
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,0        ;nomer nakopitelya


   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,12       ;nomer dorozhki
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   CALL WAIT_INTERRUPT  ;ozhidaem preryvaniya ot NGMD
;---ozhidaem ustanovki golovki (25 msek.)
   MOV  CX,1750     ;schetchik cikla zaderzhki (dlya IBM PC i XT)
WAIT_SETTLE:  LOOP WAIT_SETTLE   ;ozhidaem 25 msek.
;---nachinaem inicializaciyu mikroshemy DMA
   MOV  AL,46H      ;kod chteniya dannyh kontrollera NGMD
   OUT  12,AL       ;posylaem kod po dvum adresam
   OUT  11,AL       ;
;---vychislyaem adres bufera
   MOV  AX,OFFSET BUFFER   ;berem smeshchenie bufera v DS
   MOV  BX,DS       ;pomeshchaem DS v BX
   MOV  CL,4        ;gotovim vrashchenie starshego nibla
   ROL  BX,CL       ;vrashchaem mladshie 4 bita
   MOV  DL,BL       ;kopiruem DL v BL
   AND  DL,0FH      ;chistim starshij nibl v DL
   AND  BL,0F0H     ;chistim mladshij nibl v BX
   ADD  AX,BX       ;skladyvaem
   JNC  NO_CARRY    ;esli ne bylo perenosa, to # stranicy v DL
   INC  DL          ;uvelichivaem DL, esli byl perenos
NO_CARRY:   OUT  4,AL  ;posylaem mladshij bajt adresa
   MOV  AL,AH       ;sdvigaem starshij bajt
   OUT  4,AL        ;posylaem mladshij bajt adresa
   MOV  AL,DL       ;zasylaem nomer stranicy
   OUT  81H,AL      ;posylaem nomer stranicy

;---konec inicializacii
   MOV  AX,511      ;znachenie schetchika
   OUT  5,AL        ;posylaem mladshij bajt
   MOV  AL,AH       ;gotovim starshij bajt
   OUT  5,AL        ;posylaem starshij bajt
   MOV  AL,2        ;gotovim razreshenie kanala 2
   OUT  10,AL       ;DMA ozhidaet dannye
;---poluchaem ukazatel' na bazu diska
   MOV  AL,1EH      ;nomer vektora, ukazyvayushchego na tablicu
   MOV  AH,35H      ;nomer funkcii
   INT  21H         ;vypolnyaem funkciyu
;---posylaem parametry chteniya
   MOV  AH,66H      ;kod chteniya odnogo sektora
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,0        ;nomera golovki i nakopitelya
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,12       ;nomer dorozhki
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,0        ;nomer golovki
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,1        ;nomer zapisi
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,ES:[BX]+3  ;kod razmera sektora
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,ES:[BX]+4  ;nomer konca dorozhki


   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,ES:[BX]+5  ;dlina sdviga
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   MOV  AH,ES:[BX]+6  ;dlina dannyh
   CALL OUT_FDC     ;posylaem kontrolleru NGMD
   CALL WAIT_INTERRUPT  ;ozhidaem preryvanie ot NGMD
;---chitaem rezul'tiruyushchie bajty
   MOV  CX,7        ;berem 7 bajtov statusa
   LEA  BX,STATUS_BUFFER  ;pomeshchaem v bufer statusa
NEXT:   CALL IN_FDC  ;poluchaem bajt
   MOV  [BX],AL     ;pomeshchaem v bufer
   INC  BX          ;ukazyvaem na sleduyushchij bajt bufera
   LOOP NEXT        ;povtoryaem operaciyu
;---vyklyuchenie motora
   MOV  DX,3F2H     ;adres registra cifrovogo vyvoda
   MOV  AL,12       ;ostavlyaem bity 3 i 4
   OUT  DX,AL       ;posylaem novuyu ustanovku
   RET              ;konec procedury
SECTOR_READ      ENDP

WAIT_INTERRUPT   PROC      ;ozhidanie preryvaniya ot NGMD
;---upravlenie statusom preryvaniya 6 v bajte statusa BIOS
   MOV  AX,40H      ;segment oblasti dannyh BIOS
   MOV  ES,AX       ;pomeshchaem v ES
   MOV  BX,3EH      ;smeshchenie dlya bajta statusa
AGAIN:   MOV  DL,ES:[BX]  ;poluchaem bajt
   TEST DL,80H      ;proveryaem bit 7
   JZ   AGAIN       ;do teh por poka ne ustanovlen
   AND  DL,01111111B   ;sbrasyvaem bit 7
   MOV  ES:[BX],DL  ;zamenyaem bajt statusa
   RET
WAIT_INTERRUPT   ENDP

OUT_FDC          PROC      ;posylaem bajt iz AH FDC
   MOV  DX,3F4H     ;adres porta registra statusa
KEEP_TRYING:  IN   AL,DX   ;poluchaem znachenie
   TEST AL,128      ;bit 7 ustanovlen?
   JZ   KEEP_TRYING ;esli net, to snova proveryaem
   INC  DX          ;ukazyvaem na registr dannyh
   MOV  AL,AH       ;peredavaemoe znachenie v AH
   OUT  DX,AL       ;posylaem znachenie
   RET
OUT_FDC          ENDP

IN_FDC           PROC  ;poluchaem bajt ot FDC v AL
   MOV  DX,3F4H     ;adres porta registra statusa
ONCE_AGAIN:  IN   AL,DX   ;poluchaem znachenie
   TEST AL,128      ;bit 7 ustanovlen?
   JZ   KEEP_TRYING ;esli net, to proveryaem snova
   INC  DX          ;ukazyvaem na registr dannyh
   IN   AL,DX       ;chitaem bajt iz registra dannyh
   RET
IN_FDC           ENDP





   CHtenie  ili zapis' opredelennyh sektorov diska v osnovnom  is-
pol'zuetsya pri dostupe k katalogam diska ili ego tablice razmeshche-
niya  fajlov, sektora dlya kotoryh vsegda raspolozheny v odnom i tom
zhe meste.  V to vremya kak chtenie  sektorov  dostatochno bezobidno,
zapis' absolyutnogo sektora trebuet chtoby kod byl tshchatel'no prove-
ren pered pervym ispol'zovaniem. Oshibka mozhet sdelat' katalog ili
tablicu razmeshcheniya fajlov nechitaemymi, chto ekvivalentno  razrushe-
niyu vseh dannyh na diske.
   Kak DOS tak i BIOS  predostavlyayut  funkcii dlya chteniya i zapisi
opredelennyh  sektorov.  Odnako oni ukazyvayut sektora po-raznomu.
Dlya IBM PC, XT i PCjr procedura BIOS  trebuet informacii o nomere
storony (0 ili 1), nomere dorozhki (0-39) i nomere sektora  (1-8).
Iz-za  ogranicheniya  maksimal'nogo  nomera  sektora ravnogo 8 etot
metod prakticheski bespolezen dlya etih mashin.  Odnako dlya AT nomer
sektora mozhet menyat'sya do  8,  9  ili  15,  a chislo dorozhek mozhet
menyat'sya do 39 ili 79.  Funkcii DOS ukazyvayut sektor odnim  nome-
rom, kotoryj nazyvaetsya  logicheskim  nomerom  sektora.  Nachinaya s
naruzhnogo  oboda  diska, sektoram  prisvaivayutsya  posledovatel'no
vozrastayushchie nomera. |tot metod mozhet byt' ispol'zovan dlya diskov
proizvol'nogo razmera i tipa.
   Otschet  logisekih sektorov nachinaetsya so storony 0  dorozhki  0
sektora 1 i prodolzhaetsya  na  storone  1  s dorozhki 0, posle chego
perehodit na storonu 0 dorozhku 1 i t.d. (Na bol'shih fiksirovannyh
diskah snachala prohoditsya ves' vneshnij cilindr.) V zavisimosti ot
togo kak byl formatirovan disk, pri perehode na sleduyushchuyu dorozhku
logicheskij nomer sektora uvelichivaetsya na opredelennuyu  velichinu.
Dlya disket emkost'yu 360K kazhdaya  dorozhka  (s uchetom obeih storon)
dobavlyaet  k  logicheskomu nomeru 18.  Odnako  vychisleniya  nemnogo
uslozhnyayutsya tem, chto  otschet  nachinaetsya  s  nulya.  Takim obrazom
pervyj  sektor  na dorozhke 3 storony 2 dolzhen imet' nomer  ravnyj
3*18 dlya dorozhek 0-2 plyus 9 dlya storony 0 dorozhki 3 plyus edinica,
ukazyvayushchaya na pervyj sektor dorozhki 3 storony 1. |ta summa ravna
64. Logicheskij nomer sektora na 1 men'she etogo chisla. Na ris. 5-4
sravnivaetsya metody ukazaniya sektora DOS i BIOS.

   Vysokij uroven'.

   Bejsik ne predostavlyaet pryamogo dostupa k sektoram diska. Nado
ispol'zovat' sleduyushchuyu proceduru na  mashinnom yazyke. V prilozhenii
G ob®yasnyaetsya logika vzaimodejstviya s etoj proceduroj.  V primere
chitaetsya 9 sektorov dorozhki  3  storony  1 diskety emkost'yu 360K.
Sama  procedura  razmeshchaetsya v pamyati, nachinaya s adresa  segmenta
&H1000, a soderzhimoe sektorov razmeshchaetsya,  nachinaya s segmentnogo
adresa &H2000 (napominaem, chto absolyutnyj adres raven segmentnomu
adresu, umnozhennomu na 16).  Dlya  togo chtoby zapisat' na disk so-
derzhimoe  etogo  bufera nado izmenit' v dannyh programmy  sed'moj
bajt s konca &H25 na &H26. Vse ostal'noe ostaetsya neizmennym.

100 DEFINT A-Z       'vse peremennye budut celymi
110 DATA &H55, &H8B, &HEC, &H1E, &H8B, &H76, &H0C, &H8B
120 DATA &H04, &H8B, &H76, &H0A, &H8B, &H14, &H8B, &H76


130 DATA &H08, &H8B, &H0C, &H8B, &H76, &H06, &H8A, &H1C
140 DATA &H8E, &HD8, &H8B, &HC3, &H8B, &H00, &H00, &HCD
150 DATA &H25, &H59, &H1F, &H5D, &HCA, &H08, &H00

160 DEF SEG = &H1000     'pomeshchaem proceduru po adresu &H10000
170 FOR N = 0 TO 38      'dlya kazhdogo bajta procedury
180 READ Q: POKE N,Q     'chitaem bajt i pomeshchaem ego v pamyat'
190 NEXT                 'sleduyushchij bajt
200 READSECTOR = 0       'vypolnyaem kod, nachinaya s pervogo bajta
210 BUFFER = &H2000      'bufer dlya dannyh imeet adres &H20000
220 LOGICALNUMBER = 62   'logicheskij nomer sektora raven 62
230 NSECTORS = 9         'chislo schityvaemyh sektorov
240 DRIVE = 0            'nomer nakopitelya (0 = A)
250 CALL READSECTOR (BUFFER, LOGICALSECTORS, NSECTORS, DRIVE)
260 'teper' sektora v pamyati, nachinaya s adresa 2000:0000

   Srednij uroven'.

   BIOS ispol'zuet funkciyu 2 preryvaniya 13H dlya chteniya sektorov i
funkciyu 3 preryvaniya 13H dlya zapisi sektorov.  V oboih sluchayah DL
dolzhen soderzhat' nomer  nakopitelya  ot 0 do 3, gde 0 = A, 1 = B i
t.d.,  DH  - nomer golovki (storony), 0-1.  CH  dolzhen  soderzhat'
nomer dorozhki ot 0 do 39, a  CL  -  nomer  sektora ot 0 do 8.  AL
soderzhit chislo sektorov, kotoroe neobhodimo schitat'.  Dopuskaetsya
srazu chitat' ne bolee vos'mi  sektorov,  chto bolee chem dostatochno
dlya bol'shinstva celej.  ES:BX dolzhny ukazyvat' na nachalo bufera v
pamyati, kuda budut pomeshchat'sya dannye  ili otkuda oni budut brat'-
sya.   Pri vozvrate AL budet soderzhat' chislo prochitannyh ili zapi-
sannyh sektorov.  Esli operaciya  uspeshna,  to flag perenosa budet
raven  nulyu.  Esli on raven 1, to AH budet soderzhat' bajt statusa
diskovoj operacii, opisannyj v [5.4.8].

;---v segmente dannyh
BUFFER     DB   4000 DUP(?)  ;sozdaem bufer

;---chitaem sektora
   MOV  AX,SEG BUFFER       ;ES:BX dolzhny ukazyvat' na bufer
   MOV  ES,AX               ;
   MOV  BX,OFFSET BUFFER    ;
   MOV  DL,0                ;nomer nakopitelya
   MOV  DH,0                ;nomer golovki
   MOV  CH,0                ;nomer dorozhki
   MOV  CL,1                ;nomer sektora
   MOV  AL,1                ;chislo sektorov dlya chteniya
   MOV  AH,2                ;nomer funkcii chteniya
   INT  13H                 ;

   Preryvaniya DOS 25H i 26H chitayut i zapisyvayut absolyutnye sekto-
ra diska, sootvetstvenno. Nado pomestit' logicheskij nomer starto-
vogo sektora v DX, a DS:BX dolzhny ukazyvat' na bufer. CX soderzhit
chislo  sektorov dlya chteniya ili zapisi, a AL -  nomer  nakopitelya,
gde 0 = A, 1 = B  i  t.d.  Procedury  portyat  vse registry, krome


segmentnyh. Pri vozvrate registr flagov ostaetsya na steke, ostav-
lyaya stek nevyrovnennym.  Ne  zabud'te  vytolknut' eto znachenie so
steka  srazu posle vozvrata (v primere eto znachenie vytalkivaetsya
v CX).

;---v segmente dannyh
BUFFER      DB  DUP 5000(?)   ;sozdaem bufer

;---chitaem sektora
   PUSH DS                 ;sohranyaem registry
   MOV  AX,SEG BUFFER      ;DS:BX dolzhny ukazyvat' na bufer
   MOV  DS,AX              ;
   MOV  BX,OFFSET BUFFER   ;
   MOV  DX,63              ;logicheskij nomer sektora
   MOV  CX,9               ;chitaem vsyu dorozhku
   MOV  AL,0               ;nakopitel' A
   INT  25H                ;funkciya chteniya sektorov
   POP  CX                 ;vytalkivaem so steka flagi
   POP  DS                 ;vosstanavlivaem registry
   JNC  NO_ERROR           ;esli net oshibki, to na prodolzhenie
   CMP  AH,3               ;proverka vozmozhnyh oshibok
    .
    .
NO_ERROR:                  ;prodolzhenie programmy

   Esli pri vozvrate flag perenosa raven 1, to proizoshla oshibka i
v etom sluchae AH i AL soderzhat dva otdel'nyh bajta statusa  oshib-
ki. Esli AH = 4, to ukazannyj sektor ne najden, a esli AH = 2, to
disk neverno otformatirovan.  Esli AH = 3, to byla popytka zapisi
na disketu, zashchishchennuyu ot zapisi. Vse ostal'nye znacheniya AH govo-
ryat ob apparatnoj oshibke.

   Nizkij uroven'.

   Diskovye operacii na nizkom urovne trebuyut pryamogo  programmi-
rovaniya mikroshem  kontrollera  NGMD  i pryamogo dostupa k pamyati.
Poskol'ku  eti  operacii  vzaimosvyazany, to  oni  rassmatrivayutsya
vmeste v razdele [5.4.1].




   S  tochki zreniya programmista yazyki vysokogo urovnya rabotayut  s
posledovatel'nymi fajlami  porciyami  v odnu edinicu dannyh.  Odin
operator  "zapisyvaet"  soderzhimoe peremennoj v  posledovatel'nyj
fajl, ogranichivaya ee  paroj  vozvrat  karetki/perevod  stroki.  S
drugoj  storony,  programmisty na yazyke assemblera imeyut  delo  s
dannymi, izmeryaemymi v edinicah  zapisej.  Oni  pomeshchayut dannye v
bufer, kotoryj mozhet soderzhat' odnu ili neskol'ko zapisej, dobav-
lyaya pary vozvrat karetki/perevod stroki  mezhdu elementami dannyh,
a ne mezhdu zapisyami. Nekotorye elementy dannyh mogut prinadlezhat'
dvum zapisyam.  Togda dlya zapisi ispol'zuetsya funkciya MS DOS, poz-
volyayushchaya  zapisat' na disk odnu ili neskol'ko zapisej.   Na  vseh


urovnyah  programmirovaniya  DOS  mozhet  ne  proizvodit' fizicheskoj
zapisi  na  disk  kazhdyj raz, kogda byla podana  komanda  vyvoda.
Vmesto etogo, v  celyah  ekonomii,  DOS  ozhidaet poka ego vyhodnoj
bufer budet zapolnen, prezhde chem zapisat' dannye na disk.
   Otmetim, chto Bejsik avtomaticheski dobavlyaet v konec zapisyvae-
mogo im posledovatel'nogo fajla simvol s kodom ASCII 26 (Ctrl-Z).
|to trebovanie standartnyh tekstovyh fajlov.  Funkcii DOS ne  do-
bavlyayut etot simvol;  Vasha  programma  dolzhna sama zapisat' ego v
konec  elementa dannyh.  Fajly pryamogo dostupa ne  ogranichivayutsya
simvolom ASCII 26.

   Vysokij uroven'.

   Bejsik gotovit fajly k posledovatel'noj  zapisi, otkryvaya fajl
v rezhime posledovatel'nogo dostupa operatorom OPEN. |tot operator
imeet dve formy i kakuyu iz nih Vy  vybiraete eto delo vkusa. For-
maty etogo operatora takie:

   100 OPEN "MYFILE" FOR OUTPUT AS #1

ili

   100 OPEN "O", #1, "MYFILE"

Vo  vtoroj forme bukva "O" oboznachaet vyvod (output).  Simvol  #1
oboznachaet kodovyj  nomer,  po  kotoromu  Vy  budete vposledstvii
obrashchat'sya  k fajlu v operatorah dostupa, takih kak WRITE #1  ili
INPUT #1. V oboih  sluchayah  otkryvaetsya  fajl s imenem MYFILE dlya
priema dannyh v posledovatel'nom rezhime. Esli fajl s takim imenem
ne najden na diske, to operator OPEN  sozdast ego.  Esli zhe takoj
fajl sushchestvuet, to on budet perezapisan, t.e. posle ego zakrytiya
on budet soderzhat' tol'ko novye  zapisannye  v nego dannye. CHtoby
dobavit' dannye v konec sushchestvuyushchego posledovatel'nogo fajla, ne
izmenyaya ego predydushchego soderzhimogo, nuzhno otkryt' ego, ispol'zuya
pervuyu formu operatora OPEN  v  vide  OPEN "MYFILE" FOR APPEND AS
#1. Bolee podrobno ob etom sm. [5.3.3].
   Dannye  zapisyvayutsya v fajl s pomoshch'yu operatorov PRINT# i WRI-
TE#. Oni imeyut odinakovuyu formu:

   100 PRINT #1, S$

ili

   100 WRITE #1, X

#1 otnositsya k identifikacionnomu  nomeru fajla (deskriptoru faj-
la), prisvaivaemomu emu operatorom OPEN.  V pervom primere v fajl
zapisyvaetsya znachenie strokovoj peremennoj, a vo vtorom chislennoe
znachenie, no mozhno lyubym iz nih zapisyvat' i to i drugoe. CHislen-
nye znacheniya zapisyvayutsya  v  posledovatel'nye  fajly v strokovom
vide,  hotya oni i berutsya ne iz strokovyh peremennyh.   Naprimer,
232 yavlyaetsya 2-hbajtnym celym v strokovoj  forme, odnako esli X =
232, to operator PRINT #1, X pomeshchaet v fajl tri bajta, ispol'zuya
kody ASCII dlya cifr 2, 3 i 2.


   Operatory PRINT# i WRITE#  otlichayutsya  sposobom otdeleniya ele-
mentov dannyh v fajle. Kakoj iz nih bolee podhodyashchij opredelyaetsya
harakteristikami dannyh. Osnovnoe razlichie mezhdu dvumya operatora-
mi sostoit v tom, chto WRITE# vstavlyaet dopolnitel'nye ogranichite-
li mezhdu elementami  dannyh.  Rassmotrim  sluchaj,  kogda operator
vyvodit  neskol'ko peremennyh v vide 100 PRINT #1, A$, Z, B$  ili
100 WRITE #1, A$, Z, B$. V etom sluchae para vozvrat karetki/pere-
vod  stroki  budet pomeshchena v fajl tol'ko za  poslednej  iz  treh
peremennyh (otmetim,  chto  strokovye  i chislovye peremennye mogut
byt'  peremeshany).   Kak zhe mozhno vposledstvii vydelit'  eti  tri
peremennye? Esli byl  ispol'zovan  operator PRINT#, to nikak. Vse
tri peremennye budut ob®edineny v nepreryvnuyu stroku. Esli zhe byl
ispol'zovan operator WRITE#, to  kazhdyj element dannyh budet zak-
lyuchen  v kavychki, a mezhdu nimi budut stoyat' zapyatye.  Zatem,  pri
chtenii etih elementov iz fajla,  Bejsik  budet avtomaticheski uda-
lyat' kavychki i zapyatye, kotorye byli dobavleny operatorom WRITE#.
   Imeetsya eshche ryad menee vazhnyh voprosov.  Odin iz nih sostoit  v
tom, chto vsya problema  s  ogranichitelyami  mozhet  byt' snyata, esli
ispol'zovat'  dlya  vyvoda kazhdoj  peremennoj  otdel'nyj  operator
PRINT# ili WRITE#. V etom  sluchae  PRINT# budet otdelyat' vse ele-
menty  parami vozvrat karetki/perevod stroki, a WRITE# budet  de-
lat' to zhe samoe, no po-prezhnemu kazhdyj  element budet zaklyuchen v
kavychki  (chto  naprasno rashoduet fajlovoe prostranstvo).   Bolee
togo, dlya vyvoda strok, kotorye  sami  soderzhat kavychki, operator
WRITE# ispol'zovat' nel'zya, poskol'ku pervaya zhe vnutrennyaya kavych-
ka budet pri chtenii oshibochno  vosprinyata  kak priznak konca pere-
mennoj. I, nakonec, otmetim, chto kogda v odnom operatore vyvodit-
sya neskol'ko peremennyh, to oba  operatora  formatiruyut  dannye v
tochnosti tak zhe, kak oni formatirovalis' by pri vyvode na  termi-
nal. Takim obrazom PRINT #1, A$, B$ otdelyaet B$ ot A$, v to vremya
kak  PRINT #1, A$; B$ - net; fajl budet dobavlyat'sya nuzhnym chislom
probelov.  Operator PRINT# mozhet byt' ispo'zovan v forme PRINT #1
USING..., gde mogut byt' ispol'zovany vse obychnye ekrannye forma-
ty PRINT USING dlya formatirovaniya vyvoda v fajl.
   Voobshche govorya, bolee  ekonomichno ispol'zovat' operator PRINT#,
zapisyvaya kazhdyj raz po odnoj peremennoj. |tot metod izbavlyaet ot
izlishnih ogranichitelej  i  pozvolyaet  zatem bezoshibochno schityvat'
stroki lyubogo vida. Bolee slozhnye shemy ogranichitelej, ispol'zue-
mye pri zapisi neskol'kih  peremennyh odnim operatorom PRINT# ili
WRITE#  mogut privesti k problemam, osobenno esli odna peremennaya
budet schitana kak dve, chto  privedet  k  potere tekushchej pozicii v
fajle.
   Posle  togo kak vse dannye budut zapisany v fajl, prosto  zak-
rojte ego, chtoby obezopasit' soderzhashchiesya  v nem dannye. Napishite
CLOSE, chtoby zakryt' vse otkrytye fajly, CLOSE #1 - chtoby zakryt'
fajl #1 i CLOSE #1, #3 -  chtoby  zakryt'  fajly  #1  i #3. Hotya v
nekotoryh sluchayah Bejsik proshchaet nezakrytye fajly, no eto ne  tot
sluchaj. Operatory WRITE# i  PRINT#  vyvodyat dannye v fajlovyj bu-
fer, kotoryj zapisyvaetsya na disk tol'ko togda, kogda oni  zapol-
neny informaciej. Poslednie vvedennye dannye zapisyvayutsya na disk
operatorom  CLOSE.  Otsutstvie etogo operatora mozhet  privesti  k
potere dannyh. Vot primer:

100 OPEN "A:NEWSEQ" FOR OUTPUT AS #1  'otkryvaem fajl


110 A$ = "aaaaa"                      'gotovim tri stroki
120 B$ = "bbbbb"                      '
130 C$ = "ccccc"                      '
140 WRITE #1, A$, B$, C$              'zapis' strok
150 CLOSE                             'ochistka bufera

   Srednij uroven'.

   MS DOS mozhet pisat'  posledovatel'nye fajly kak metodom uprav-
lyayushchego bloka fajla, tak i metodom deskriptora fajlov.  Metod FCB
predostavlyaet  funkciyu  special'no  skonstruirovannuyu  dlya zapisi
posledovatel'nyh fajlov.  Metod deskriptora fajlov, s drugoj sto-
rony, imeet tol'ko funkciyu zapisi v fajl obshchego naznacheniya, no ee
legko  ispol'zovat' i dlya etoj celi.  V lyubom sluchae, sposob, ko-
torym byl otkryt fajl, vazhen pri posledovatel'nyh operaciyah. Esli
dannye  dolzhny dobavlyat'sya k posledovatel'nomu fajlu,  to  dolzhna
byt' ispol'zovana obychnaya  funkciya  otkrytiya fajla.  Odnako, esli
fajl dolzhen byt' perezapisan zanovo, to trebuetsya funkciya "sozda-
niya" fajla. |ta funkciya  obrezaet  fajl do nulevoj dliny, poetomu
ego dlina budet ravna dline zapisannyh v nego dannyh.

Metod FCB:
   Funkciya 15H preryvaniya 21H prednaznachena dlya zapisi v posledo-
vatel'nyj fajl. Nado podgotovit' upravlyayushchij blok fajla i oblast'
obmena  s diskom, kak pokazano v [5.3.5].  Esli fajl dolzhen  byt'
perezapisan, to ego nado  otkryt'  s pomoshch'yu funkcii 16H, kotoraya
"sozdaet"  fajl, obrezaya ego do nulevoj dliny.  Esli Vy  otkroete
fajl s pomoshch'yu funkcii 0FH, to ostatok  starogo fajla ostanetsya v
konce fajla, esli dlina novogo fajla budet men'she, chem starogo. S
drugoj storony, esli Vy hotite  dobavit'  dannye  k fajlu, to is-
pol'zujte funkciyu otkrytiya fajla.
   Posle  togo  kak fajl otkryt, Vy dolzhny  ustanovit'  DS:DX  na
nachalo FCB i vyzvat'  funkciyu  15H  dlya togo chtoby zaprisat' odnu
zapis'  dannyh.  Kolichestvo dannyh v zapisi zavisit ot  velichiny,
kotoraya pomeshchena v pole dliny zapisi,  raspolozhennoe so smeshcheniem
14  v  obychnom FCB, po umolchaniyu eto znachenie ravno  128  bajtam.
Esli razmer zapisi men'she, chem razmer  sektora diska 512 bajt, to
dannye budut buferizovat'sya, do teh por poka ne nakopitsya  dosta-
tochno dannyh, chtoby proizvesti  real'nuyu  zapis' na disk; poetomu
zapisi  v posledovatel'nyj fajl mogut uspeshno  zapisyvat'sya  dazhe
esli nakopitel' ne vklyuchen. Pri  zakrytii fajla vse dannye ostav-
shiesya v bufere sbrasyvayutsya na disk. Pri vozvrate iz funkcii 15H,
AL raven 0, esli operaciya uspeshna, 1 - esli disk polon i 2 - esli
segment oblasti obmena dannyh slishkom mal.
   V  sleduyushchem primere na disk zapisyvayutsya 5 zapisej dlinoj 256
bajtov.  Zapisi mogut byt' naborom  tekstovyh dannyh.  |ti dannye
raspolozheny v oblasti pamyati, pomechennoj metkoj WORKAREA.  Ukaza-
tel' na DTA pervonachal'no ustanavlivaetsya na nachalo etoj oblasti,
a  posle zapisi kazhdoj zapisi ustanovka DTA menyaetsya takim  obra-
zom, chtoby on ukazyval na 256  bajtov  vyshe.  Otmetim, chto obychno
dlya  takoj  rabochej oblasti otvoditsya special'naya oblast'  pamyati
[1.3.1], no v dannom  primere  dlya  prostoty  ispol'zuetsya  bufer
raspolozhennyj v segmente dannyh.


;---v segmente dannyh
WORKAREA     DB  2000 DUP (?)   ;bufer dannyh
FCB          DB  1,'FILENAMEEXT',25 DUP (0)

;---DTA dolzhen ukazyvat' na rabochuyu oblast'
   LEA  DX,WORKAREA   ;DS:DX ukazyvayut na DTA
   MOV  DI,DX         ;sohranyaem kopiyu
   MOV  AH,1AH        ;funkciya ustanovki DTA
   INT  21H           ;ustanavlivaem DTA
;---otkryvaem fajl
   MOV  AH,16H        ;nomer funkcii
   LEA  DX,FCB        ;DS:DX ukazyvayut na FCB
   INT  21H           ;otkryvaem fajl
;---ustanavlivaem razmer zapisi
   LEA  BX,FCB        ;BX ukazyvaet na FCB
   MOV  AX,256        ;razmer zapisi 256 bajtov
   MOV  [BX]+14,AX    ;zapisyvaem v pole razmera zapisi
;---posylaem dannye v fajl
   MOV  CX,5          ;chislo zapisej
NEXT_REC:  MOV  AH,15H   ;funkciya zapisi
   LEA  DX,FCB        ;ukazyvaem na FCB
   INT  21H           ;zapisyvaem dannye
   CMP  AL,2          ;proverka na oshibki
   JE   CONTINUE      ;i ih obrabotka
   CMP  AL,1          ;
   JE   DISK_FULL     ;
;---perenos vypolnen, pereustanavlivaem DTA
   ADD  DI,256        ;sdvigaemsya na 1 zapis'
   MOV  DX,DI         ;DS:DX ukazyvayut na novyj DTA
   MOV  AH,1AH        ;funkciya ustanovki DTA
   INT  21H           ;ustanovka novoj pozicii
   LOOP NEXT_REC:     ;idem na sleduyushchuyu zapis'

;---pozdnee, zakryvaem fajl
   LEA  DX,FCB        ;DS:DX ukazyvayut na FCB
   MOV  AH,10H        ;funkciya zakrytiya fajla
   INT  21H           ;zakryvaem fajl

   Metod upravlyayushchego bloka fajla ne slishkom udoben dlya  dobavle-
niya zapisej v  konec  sushchestvuyushchego  posledovatel'nogo  fajla.  V
otlichii ot metoda deskriptora fajla, kotoryj pozvolyaet ukazat' na
konec fajla, zdes' Vy dolzhny manipulirovat' polyami tekushchej zapisi
i tekushchego bloka.  Nuzhno  schitat'  poslednyuyu, nesushchuyu informaciyu,
zapis' v DTA, a zatem zapolnit' pustoe prostranstvo v nem  pervoj
zapis'yu dannyh, kotorye Vy  hotite  dobavit'.  Zatem perezapishite
zapis' na ee staroe mesto v fajle, posle chego Vy mozhete dobavlyat'
skol'ko hotite novyh  zapisej.  Fajl  dolzhen byt' otkryt funkciej
0FH.

Metod deskriptora fajla:
   Neobhodima  vnimatel'nost'  pri otkrytii fajla dlya  posledova-
tel'nogo vyvoda metodom deskriptora  fajla. Poskol'ku ta zhe samaya


funkciya  ispol'zuetsya dlya zapisi v fajl pryamogo dostupa,  to  pri
zakrytii fajla ego  dlina  ne  ustanavlivaetsya  ravnoj  poslednej
pozicii  fajlovogo ukazatelya.  Voz'mem, naprimer,  sluchaj,  kogda
tekstovyj fajl razmerom 2000  bajtov schityvaetsya s diska, a zatem
v processe obrabotki v pamyati ego dlina umen'shaetsya do 1000 bajt.

Esli fajl byl otkryt  prostoj  komandoj  otkrytiya  fajla (funkciya
3DH),  to  posle togo, kak novaya, bolee  korotkaya,  versiya  fajla
budet zapisana na disk i fajl  budet  zakryt, ego dlina ostanetsya
ravnoj 2000 bajtam, iz kotoryh novyj tekst budet zanimat'  pervuyu
tysyachu bajtov. Po etoj  prichine,  pri  otkrytii posledovatel'nogo
fajla dlya perezapisi nado ispol'zovat' funkciyu 3CH preryvaniya 21H
[5.3.2].  |ta funkciya obychno sozdaet novyj fajl, no esli fajl uzhe
sushchestvuet, to on  obrezaetsya  do  nulevoj  dliny. Dlya dobavleniya
dannyh  v posledovatel'nyj fajl nado ispol'zovat' obychnuyu funkciyu
otkrytiya fajla, 3DH preryvaniya 21H [5.3.3].
   Rassmotrim snachala sluchaj polnoj perezapisi fajla. Posle togo,
kak fajl otkryt funkciej 3CH, fajlovyj ukazatel'  ustanavlivaetsya
ravnym nulyu, poetomu net nuzhdy ustanavlivat' ego. Pomestite nomer
fajla  v BX, a chislo zapisyvaemyh bajtov v CX.  Zatem  ustanovite
DS:DX na pervyj bajt  vyvodimyh  dannyh  i  vypolnite funkciyu 40H
preryvaniya 21H.  Pri vozvrate, esli flag perenosa ustanovlen,  to
byla oshibka i AX soderzhit 5, esli byla oshibka diskovogo nakopite-
lya i 6 - esli nevernyj nomer fajla.  V protivnom sluchae, AX budet
soderzhat' chislo real'no  zapisannyh  bajtov; pri nesovpadenii ve-
royatnee vsego problema sostoit v tom, chto disk polon. Ne zabud'te
o procedure vosstanovleniya pri sboyah, tak kak pri krahe programmy
pervonachal'noe  soderzhimoe  fajla budet uteryano, tak kak  on  byl
obrezan do nulevoj dliny.  Kak  proveryat'  diskovoe  prostranstvo
opisano v [5.1.2]. Vot primer:

;---v segmente dannyh
PATH         DB    'B:FILENAME.EXT',0   ;put' k fajlu
DATA_BUFFER  DB    2000 DUP (?)

;---otkryvaem fajl s pomoshch'yu funkcii "sozdaniya"
   LEA  DX,PATH          ;DS:DX ukazyvayut na put' k fajlu
   MOV  CX,0             ;atributy fajly (zdes' obychnye)
   MOV  AH,3CH           ;nomer funkcii
   INT  21H              ;otkryvaem fajl
   JC   OPEN_ERROR       ;proverka na oshibku
   MOV  HANDLE,AX        ;zapominaem nomer fajla
;---zapisyvaem v fajl 1000 bajtov
   MOV  AH,40H           ;nomer funkcii
   MOV  BX,HANDLE        ;nomer fajla v BX
   MOV  CX,1000          ;chislo bajt, kotorye nado zapisat'
   LEA  DX,DATA_BUFFER   ;DS:DX ukazyvayut na bufer dannyh
   INT  21H              ;zapisyvaem dannye
   JC   OUTPUT_ERROR     ;proverka na oshibki
   CMP  CX,2000          ;i ih obrabotka
   JNE  FULL_DISK        ;


   Dlya  dobavleniya zapisej v posledovatel'nyj fajl  nado  otkryt'
fajl s pomoshch'yu funkcii 3DH  preryvaniya  21H, pomeshchaya 1 v AL, esli
programma budet tol'ko pisat' dannye i 2, esli programma budet  i
chitat' i pisat'. Dlina fajla  ostaetsya  neizmennoj, hotya on budet
uvelichivat'sya po mere dobavleniya dannyh.  Fajlovyj ukazatel' dol-
zhen byt' ustanovlen na  konec  fajla,  inache  sushchestvuyushchie dannye
budut perezapisany.  |to vypolnyaetsya funkciej 42H preryvaniya 21H.
Pomestite nomer podfunkcii 2  v  AL,  dlya  ustanovki ukazatelya na
konec  fajla,  a nomer fajla pomestite v BX.  CX:DX ukazyvayut  na
smeshchenie  otnositel'no  konca  fajla,  nachinaya  s  kotorogo budet
proizvodit'sya zapis', poetomu obnulite eti registry. Zatem vypol-
nite funkciyu ustanovki ukazatelya. Pri vozvrate ustanovlennyj flag
perenosa  indiciruet  oshibku, pri etom v AX budet 1,  esli  nomer
podfunkcii v AL byl neveren, i 6  - esli neverno byl ukazan nomer
fajla.   Posle  togo kak fajlovyj ukazatel'  ustanovlen  operaciya
zapisi vypolnyaetsya v tochnosti kak v predydushchem sluchae:

;---v segmente dannyh
PATH          DB  'B:FILENAME.EXT',0   ;put' k fajlu
DATA_BUFFER   DB  1000 DUP(?)

;---otkryvaem fajl
   LEA  DX,PATH       ;DS:DX ukazyvayut na put'
   MOV  AL,1          ;kod otkrytiya tol'ko dlya zapisi
   MOV  AH,3DH        ;nomer funkcii
   INT  21H           ;otkryvaem fajl
   JC   OPEN_ERROR    ;uhod po oshibke
   MOV  HANDLE,AX     ;sohranyaem nomer fajla
;---ustanovka fajlovogo ukazatelya na konec fajla
   MOV  BX,AX         ;nomer fajla v BX
   MOV  CX,0          ;CX:DX dayut smeshchenie otnositel'no konca
   MOV  DX,0          ;
   MOV  AL,2          ;kod dlya konca fajla
   MOV  AH,42H        ;funkciya ustanovki ukazatelya
   INT  21H           ;ustanavlivaem ukazatel'
   JC   POINTER_ERROR ;proverka na oshibku
;---dobavlyaem k fajlu 300 bajtov
   MOV  AH,40H        ;nomer funkcii
   MOV  BX,HANDLE     ;nomer fajla v BX
   MOV  CX,300        ;chislo zapisyvaemyh bajtov
   LEA  DX,DATA_BUFFER   ;DS:DX ukazyvayut na bufer dannyh
   INT  21H           ;dobavlyaem dannye
   JC   OUTPUT_ERROR  ;proverka na oshibki
   CMP  CX,300        ;i ih obrabotka
   JNE  FULL_DISK     ;




   CHtenie iz posledovatel'nogo fajla malo chem otlichaetsya ot zapi-
si v nego, za isklyucheniem togo, chto  process obratnyj.  V Bejsike
dannye berutsya iz fajla i prisvaivayutsya otdel'nym peremennym  ili
elementam massiva dannyh. V  yazyke assemblera dannye pomeshchayutsya v


bufer,  raspolozhennyj v pamyati.  V poslednem sluchae dannye  pere-
dayutsya po zapisyam i programma dolzhna  sama vydelyat' elementy dan-
nyh,  sostavlyayushchie zapisi.  V etom sluchae pod zapis'yu  ponimaetsya
porciya dannyh, kotoraya schityvaetsya iz fajla.

   Vysokij uroven'.

   CHtenie posledovatel'nyh fajlov v Bejsike proshche, chem ih zapis',
poskol'ku  imeetsya tol'ko dve vozmozhnosti, kak obrashchat'sya s nimi,
v zavisimosti ot togo, kakie  simvoly  v fajle ispol'zuyutsya v ka-
chestve ogranichitelej elementov dannyh. Operator INPUT# raspoznaet
zapyatye i  kavychki,  kak  razdeliteli  dannyh,  tak zhe kak i pary
vozvrat karetki/perevod stroki.  Operator LINE INPUT#  raspoznaet
tol'ko  kombinacii  CR/LF,  poetomu  on  mozhet ispol'zovat'sya dlya
chteniya  celyh strok teksta, soderzhashchih drugie ogranichiteli.   |ta
vozmozhnost' udobna pri obrabotke tekstov.
   Dlya chteniya treh elementov operatorom  INPUT#, snachala otkrojte
fajl,  kak obsuzhdalos' v [5.3.3] (naprimer, OPEN  "A:NEWSEQ"  FOR
INPUT AS #1). Esli fajl  byl  otkryt  pod  nomerom 1, to operator
INPUT  #1,  X$, Y$, Z$ prisvoit znachenie  pervyh  treh  elementov
dannyh trem strokovym peremennym.  Pri vvode chislovyh peremennyh,
naprimer,  INPUT  #1, X, Y, Z neobhodimo,  chtoby  sootvetstvuyushchie
dannye v fajle byli chislovymi.   CHislo s dvojnoj tochnost'yu dolzhno
schityvat'sya  v peremennuyu dvojnoj tochnosti, s tem chtoby ona mogla
hranit' vosem' bajtov takogo  chisla.  Drugoj sposob prochitat' tri
elementa dannyh sostoit v razmeshchenii ih v massive:

100 DIM ITEM$(40)       'sozdaem massiv strok iz 40 elementov
110 FOR N = 0 TO 39     'dlya kazhdogo elementa
120 INPUT #1, ITEM$(N)  'schityvaem ego i pomeshchaem v massiv
130 NEXT                '

CHtoby  prochitat' n-nyj element posledovatel'nogo fajla  programma
dolzhna prochitat' vse  predshestvuyushchie  emu  elementy.  Nado prosto
sozdat' cikl, v kotorom budut schityvat'sya elementy dannyh, no  ne
sohranyat' eti dannye po mere ih poyavleniya.
   Operator LINE INPUT# dejstvuet v osnovnom analogichno operatoru
INPUT#,  za isklyucheniem togo, chto on mozhet prinimat' tol'ko  odnu
peremennuyu i eto vsegda  strokovaya  peremennaya.  Peremennaya mozhet
byt'  dlinoj do 254 simvolov i eto maksimal'no dopustimyj  razmer
strokovyh peremennyh  v  Bejsike.   Para  vozvrat karetki/perevod
stroki,  soderzhashchayasya v fajle, vklyuchaetsya v stroku,  vozvrashchaemuyu
operatorom LINE INPUT#. |to svojstvo pozvolyaet obnaruzhivat' konec
paragrafa v tekstovom fajle.
   Funkciya  EOF (konec fajla) mozhet byt' ispol'zovana dlya oprede-
leniya togo, vse li  elementy  fajla  byli  prochitany. |ta funkciya
vozvrashchaet -1, esli fajl ischerpan i 0 - v protivnom sluchae. Funk-
cii trebuetsya nomer fajla, pod  kotorym  on byl otkryt; naprimer,
esli  byl byl otkryt kak #2, to X = EOF(2).  V sleduyushchem  primere
ves' tekstovyj fajl schityvaetsya v massiv:

100 OPEN "TEXT.AAA" FOR INPUT AS #2   'otkryvaem fajl
110 DIM TEXT$(500)                    'ne bolee 500 strok
120 LINECOUNT = 0                     'schetchik strok


130 LINE INPUT #2, TEXT$(LINECOUNT)   'poluchaem stroku
140 IF EOF(2) THEN 170                'proverka na konec fajla
150 LINECOUNT = LINECOUNT + 1         'uvelichivaem schetchik
160 GOTO 130                          'na sleduyushchuyu stroku
170 ...                               'fajl prochitan

   Operator INPUT$ chitaet  iz  posledovatel'nogo  fajla ukazannoe
chislo simvolov.  Na samoj programme lezhit zabota o vydelenii  ot-
del'nyh elementov  dannyh.  Format  etogo operatora dlya chteniya 30
simvolov  iz fajla #1 takoj: S$ = INPUT$(30,#1).  Hotya Vy  mozhete
ukazyvat' chislo bajt dlya  chteniya,  neobhodimo  chtoby eto chislo ne
prevoshodilo  254,  poskol'ku eto maksimal'nyj  razmer  strokovoj
peremennoj, v kotoruyu pomeshchayutsya dannye. INPUT$ polezen pri pere-
dache massy dannyh v nepreryvnuyu oblast' pamyati.  Naprimer, v sle-
duyushchem primere delaetsya damp  pervyh 200 bajtov posledovatel'nogo
fajla v bufer monohromnogo displeya, s tem chtoby oni byli vyvedeny
na ekran, vklyuchaya upravlyayushchie kody:

100 OPEN "A:NEWFILE" FOR INPUT AS #1   'otkryvaem fajl
110 CLS: DEF SEG = &HB000              'ukazyvaem na bufer
120 FOR N = 0 TO 9                     'poluchaem 10 grupp
130 S$ = INPUT$(20,#1)                 'po 20 bajtov
140 FOR M = 1 TO 20                    'berem kazhdyj bajt
150 POKE N*160 + M*2, ASC(MID$(S$,M,1) 'i pomeshchaem ego v bufer
160 NEXT M       'perehod k sleduyushchemu bajtu
170 NEXT N       'perehod k sleduyushchej gruppe

   Srednij uroven'.

   Kak i dlya vseh fajlovyh  operacij MS DOS mozhet chitat' posledo-
vatel'nye fajly kak metodom upravlyayushchego bloka fajla, tak i meto-
dom deskriptora fajlov. Tol'ko  pervyj  iz nih imeet funkciyu spe-
cial'no prednaznachennuyu dlya chteniya posledovatel'nyh fajlov. Metod
deskriptora fajlov ispol'zuet bolee obshchuyu funkciyu, manipuliruya ej
osobym obrazom, trebuemym dlya posledovatel'nyh fajlov.

Metod FCB:
   Funkciya 14H preryvaniya 21H chitaet posledovatel'nye fajly. Nado
sozdat' upravlyayushchij blok  fajla  i  oblast'  obmena s diskom, kak
ob®yasneno v [5.3.5].  Fajl dolzhen byt' otkryt funkciej 0FH prery-
vaniya 21H [5.3.3].   DS:DX  dolzhny  ukazyvat' na pervyj bajt FCB,
posle  chego funkciya 14H budet chitat' po odnoj zapisi iz fajla pri
kazhdom vyzove.  Vy mozhete ustanovit' razmer zapisi po smeshcheniyu 14
v FCB.  |to nado delat' posle togo, kak fajl otkryt, tak kak  pri
otkrytii fajla DOS vstavlyaet  v  eto  pole znachenie po umolchaniyu,
ravnoe 128.

   Kazhdyj  raz  pri vyzove funkcii dannye  zagruzhayutsya v  pamyat',
nachinaya s pervogo bajta DTA.  Esli DTA ispol'zuetsya kak nebol'shoj
vremennyj bufer, to pered chteniem sleduyushchej zapisi soderzhimoe DTA
dolzhno byt' pereneseno v oblast' dannyh fajla, otvedennuyu v pamya-
ti.   Mozhno naoborot ustanovit' ukazatel' DTA na startovyj  adres
pamyati, nachinaya s kotorogo budet razmeshchat'sya fajl, a posle chteniya


kazhdoj zapisi ukazatel' uvelichivat' na razmer zapisi, s tem chtoby
on ukazyval na mesto, gde dolzhna byt' sleduyushchaya zapis'.
   Ustanovkoj polej  tekushchej  zapisi  (DB,  smeshchenie 1FH) i bloka
tekushchej  zapisi (DW, smeshchenie 0CH) otlichnymi ot nulya,  posledova-
tel'nyj mozhet chitat'sya,  nachinaya  s  lyubogo trebuemogo mesta (us-
tanovka  dolzhna byt' sdelana posle otkrytiya FCB).  Posle  kazhdogo
chteniya pole tekushchej zapisi  avtomaticheski  uvelichivaetsya  na 1, a
posle  chteniya 128 zapisej uvelichivaetsya pole tekushchego bloka.  Pri
vozvrate AL raven 0, esli vsya zapis' uspeshno prochitana. Pri obna-
ruzhenii konca fajla AL budet soderzhat' 1, esli funkciya 14H voobshche
ne vozvratila dannyh i 3 - esli zapis' prochitana chastichno.
   V privedennom primere iz fajla schityvayutsya dve zapisi i posle-
dovatel'no  pomeshchayutsya  v nuzhnuyu oblast' pamyati.   Razmer  zapisi
ustanovlen ravnym 256 bajtam.  Zapisi schityvayutsya v cikle i posle
togo,  kak  pervaya  zapis' schitana, ukazatel' na  DTA  izmenyaetsya
takim obrazom, chtoby on  ukazyval  na sleduyushchij pustoj bajt v ob-
lasti dannyh.

;---pomeshchaem FCB v segment dannyh
FCB          DB  0,'OLDDATA DAT', 25 DUP(0)
DATA_AREA    DB  512 DUP (?)    ;ispol'zuem kak DTA

;---ustanavlivaem DTA na nachalo oblasti dannyh
   LEA  DX,DATA_AREA      ;DS:DX ukazyvayut na DTA
   MOV  DI,DX             ;sohranyaem kopiyu
   MOV  AH,1AH            ;funkciya ustanovki DTA
   INT  21H               ;ustanavlivaem DTA
;---otkryvaem fajl
   LEA  DX,FCB            ;DS:DX ukazyvayut na FCB
   MOV  AH,0FH            ;funkciya otkrytiya fajla
   INT  21H               ;otkryvaem fajl
   CMP  AL,0              ;proverka na oshibku
   JNE  OPEN_ERROR        ;
;---ustanavlivaem razmer zapisi 256 bajt
   LEA  BX,FCB            ;DS:DX ukazyvayut na FCB
   MOV  AX,256            ;razmer zapisi
   MOV  DS:[BX]+14,AX     ;posylaem v pole razmera zapisi
;---chtenie dannyh
   MOV  CX,2              ;chislo chitaemyh zapisej
NEXT_REC:   MOV  AH,14H   ;funkciya chteniya fajla
   LEA  DX,FCB            ;DS:DX ukazyvayut na FCB
   INT  21H               ;chitaem odnu zapis'
   CMP  AL,0              ;vse v poryadke?
   JE   CONTINUE          ;
   CMP  AL,2              ;proverka na oshibku
   JE   READ_ERROR        ;
    .
    .

CONTINUE:  ADD  DI,256    ;uvelichivaem ukazatel'
   MOV  DX,DI             ;DX ukazyvaet na novuyu DTA
   MOV  AH,1AH            ;funkciya ustanovki DTA
   INT  21H               ;ustanavlivaem DTA


   LOOP NEXT_REC          ;idem na chtenie sleduyushchej zapisi
;---pozdnee, zakryvaem fajl
   LEA  DX,FCB            ;DS:DX ukazyvayut na FCB
   MOV  AH,10H            ;funkciya zakrytiya fajla
   INT  21H               ;zakryvaem fajl
   CMP  AL,0FFH           ;proverka na oshibku
   JE   CLOSE_ERROR       ;

Metod deskriptora fajlov:
   Funkciya 3FH preryvaniya 21H mozhet chitat' dannye iz fajla posle-
dovatel'no. |ta funkciya ispol'zuetsya dlya lyubogo chteniya iz fajla s
pomoshch'yu metoda deskriptora fajlov, vklyuchaya fajly pryamogo dostupa.
Fajl dolzhen byt' otkryt  funkciej  3DH preryvaniya 21H s kodom 0 v
AL, esli on otkryvaetsya tol'ko dlya chteniya, i s kodom 2 - esli  on
otkryvaetsya dlya chteniya i zapisi.  Pri otkrytii fajlovyj ukazatel'
avtomaticheski ustanavlivaetsya na pervyj bajt fajla.  Funkciya chte-
niya iz fajla ukazyvaet skol'ko bajtov dolzhno byt' schitano i posle
togo  kak eto sdelano fajlovyj ukazatel' ukazyvaet na bajt,  sle-
duyushchij za poslednim  schitannym  bajtom,  podgotavlivaya  sleduyushchee
obrashchenie k funkcii. Otmetim, chto fajlovyj ukazatel' unikalen dlya
kazhdogo fajla - operacii nad  drugimi fajlami ne menyayut ego pozi-
ciyu.
   Programma  mozhet sozdat' nebol'shoj vremennyj bufer,  razmerom,
skazhem, 512 bajt, i postoyanno  vyzyvat'  funkciyu chteniya, ne zabo-
tyas' o pozicii fajlovogo ukazatelya. Drugoj metod sostoit v schity-
vanii vsego fajla pryamo v  to  mesto  pamyati,  gde on dolzhen byt'
raspolozhen.  V etom sluchae nado prosto potrebovat', chtoby funkciya
prochitala bol'she bajtov, chem real'no  soderzhitsya v fajle, tak kak
chtenie prekrashchaetsya pri dostizhenii poslednego bajta fajla. Odnako
Vam neobhodimo znat' tochnuyu dlinu fajla, chtoby znat' gde konchayut-
sya dannye v bufere, v kotoryj Vy schitali fajl.
   Razmer  fajla mozhno opredelit', sdvinuv fajlovyj ukazatel'  na
konec fajla.  |to nado  sdelat'  srazu  zhe  posle otkrytiya fajla.
Pomestite  v  AL kod 2 i vyzovite funkciyu 42H,  dlya  togo,  chtoby
sdvinut' ukazatel' na konec  fajla.   CX i DX dolzhny soderzhat' 0,
tak  kak v protivnom sluchae ukazatel' budet sdvinut s konca fajla
na velichinu, kotoraya soderzhitsya  v  etih  registrah. Pri vozvrate
DX:AX budut soderzhat' novuyu poziciyu ukazatelya, kak smeshchenie otno-
sitel'no nachala fajla, t.e.,  v  dannom  sluchae,  dlinu fajla. Ne
zabud'te  snova vernut' fajlovyj ukazatel' na nachalo fajla, pered
tem kak chitat' ego; eto delaetsya tochno  takim zhe obrazom, za isk-
lyucheniem  togo,  chto v AL nado pomestit' 0.  Esli pri  vypolnenii
funkcii 42H voznikaet oshibka, to ustanavlivaetsya flag perenosa, a
v AX vozvrashchaetsya 1, esli neveren nomer funkcii, i 6 - esli  uka-
zan nevernyj nomer fajla.
   Teper' programma gotova dlya chteniya fajla. Nado pomestit' nomer
fajla v BX, a trebuemoe chislo bajtov v CX i vypolnit' preryvanie.
Pri vozvrate AX budet soderzhat' chislo real'no prochitannyh bajtov.
Esli AX raven nulyu, to dostignut konec fajla.  Pri drugih oshibkah
ustanavlivaetsya flag perenosa, a AX  soderzhit 5 - pri oshibke obo-
rudovaniya  i  6 - esli ukazan nevernyj nomer fajla.  V  sleduyushchem
primere v bufer pamyati  schityvaetsya  ves'  nebol'shoj fajl. Dlya u-
dobstva  bufer raspolagaetsya v segmente dannyh,  chto  sushchestvenno


uvelichivaet razmer programmy na diske.   V svoih programmah luchshe
sozdavat' bufer, ispol'zuya tehniku raspredeleniya pamyati,  opisan-
nuyu v [1.3.1].

;---v segmente dannyh
PATH        DB   'A:FILENAME.EXT'0   ;stroka puti k fajlu
DATA_BUFFER DB   1000 DUP (?)        ;bufer dannyh
HANDLE      DW   ?                   ;nomer fajla
FILESIZE    DW   ?                   ;razmer fajla

;---otkryvaem fajl
   LEA  DX,PATH            ;DS:DX ukazyvayut na put'
   MOV  AL,0               ;kod otkrytiya dlya chteniya
   MOV  AH,3DH             ;funkciya otkrytiya fajla
   INT  21H                ;otkryvaem fajl
   JC   OPEN_ERROR         ;proverka na oshibku
   MOV  HANDLE,AX          ;zapominaem nomer fajla
;---ustanavlivaem fajlovyj ukazatel' na konec fajla
   MOV  AH,42H             ;funkciya ustanovki ukazatelya
   MOV  AL,2               ;kod dlya konca fajla
   MOV  BX,HANDLE          ;nomer fajla
   MOV  CX,0               ;smeshchenie ravno nulyu
   MOV  DX,0               ;
   INT  21H                ;ustanavlivaem ukazatel'
   JC   POINTER_ERROR1     ;obrabotka oshibki
   MOV  FILESIZE,AX        ;zapominaem razmer (men'she 64K)
;---vozvrashchaem ukazatel' na nachalo
   MOV  AH,42H             ;nomer funkcii
   MOV  AL,0               ;kod dlya nachala fajla
   MOV  CX,0               ;smeshchenie ravno nulyu
   MOV  DX,0               ;
   INT  21H                ;ustanavlivaem ukazatel'
   JC   POINTER_ERROR2     ;obrabotka oshibki

;---chitaem ves' fajl
   MOV  AH,3FH             ;nomer funkcii chteniya fajla
   MOV  BX,HANDLE          ;nomer fajla
   MOV  CX,FILESIZE        ;chislo schityvaemyh bajtov
   LEA  DX,DATA_BUFFER     ;DS:DX ukazyvayut na bufer
   INT  21H                ;chitaem fajl
   JC   READ_ERROR         ;obrabotka oshibki

;---pozdnee, zakryvaem fajl
   MOV  BX,HANDLE          ;nomer fajla
   MOV  AH,3EH             ;funkciya zakrytiya fajla
   INT  21H                ;zakryvaem fajl
   JC   CLOSE_ERROR        ;obrabotka oshibki




   Fizicheski  fajly pryamogo dostupa nichem ne otlichayutsya ot posle-
dovatel'nyh fajlov, oni  otlichayutsya  tol'ko rezhimom dostupa. Fajl


pryamogo  dostupa predpolagaet, chto ego dannye organizovany v vide
zapisej fiksirovannoj dliny, takim obrazom polozhenie kazhdoj zapi-
si mozhet byt' vychisleno (v posledovatel'nyh fajlah n-nyj  element
ishchetsya putem  podscheta  razdelitelej  mezhdu elementami, nachinaya s
nachala fajla).  Operacionnaya sistema avtomaticheski vypolnyaet  eti
vychtsleniya. Odnako  lyubaya  programma  mozhet  vypolnyat' etu rabotu
sama, ustanavlivaya fajlovyj ukazatel' na nuzhnuyu poziciyu i  schity-
vaya posledovatel'no takoe chislo bajtov, kotoroe obrazuet zapis'.

   Vysokij uroven'.

   V [5.3.3] ob®yasnen  format  otkrytiya  fajdov pryamogo dostupa v
Bejsike.  V otlichii ot posledovatel'nogo fajla, fajl pryamogo dos-
tupa mozhet chitat'sya  i  zapisyvat'sya  v  odno  i to zhe vremya, bez
zakrytiya  i  povtornogo ego otkrytiya.  Operator OPEN  zavershaetsya
chislom, dayushchim razmer zapisi fajla.  Naprimer, OPEN "R", 1, "NEW-
DATA", 20 ustanavlivaet dlya fajla NEWDATA razmer zapisi v 20 bajt
(pri etom fajl otkryvaetsya kak fajl #1).
   Posle togo kak fajl otkryt,  ego  zapisi mogut byt' razbity na
sostavlyayushchie peremennye s pomoshch'yu operatora FIELD. Operator FIELD
ukazyvaet skol'ko bajtov zapisi  otvoditsya pod kazhduyu peremennuyu.
Naprimer,  zapis'  dlinoj 20 bajt mozhet byt'  razbita  operatorom
FIELD 1, 14 AS LASTNAME$, 2 AS  DEPOSIT$,  4 AS ACCTNUM$.  V etom
operatore  pervaya  cifra 1 ukazyvaet, chto dannyj  operator  FIELD
opisyvaet razbienie zapisi dlya  fajla,  otkrytogo pod nomerom #1.
Dannye  raspolagayutsya v zapisi tochno v tom poryadke, v  kakom  oni
opisany v operatore FIELD.  Opreatory RSET i LSET sdvigayut dannye
v polyah, vyravnivaya ih po pravomu (RSET) ili levomu (LSET) krayu i
zapolnyaya ostayushchiesya pustye mesta probelami.   Naprimer, dlya togo,
chtoby vstavit' familiyu "SMITH" v 14-bajtnoe pole s imenem LASTNA-
ME$, nado zapisat' RSET LASTNAME$  = "SMITH", ili esli peremennoj
N$ bylo prisvoeno znachenie "SMITH", to RSET LASTNAME$ = N$. Vmes-
to RSET mozhet byt' ispol'zovano  LSET.  Kogda vposledstvii dannye
schityvayutsya iz polya v peremennuyu, to peremennoj prisvaivayutsya vse
14 bajtov. Pri  ispol'zovanii  RSET  programma  udalit vse lishnie
probely v nachale strokovoj peremennoj, odnako esli budet  ispol'-
zovat'sya LSET, to probely budut udalyat'sya sprava.
   Otmetim, chto vse imena  peremennyh v operatore FIELD otnosyatsya
k strokovym peremennym.  V fajlah pryamogo dostupa Bejsik rassmat-
rivaet vse peremennye - vklyuchaya chislovye  - kak strokovye. CHislo-
vaya peremennaya dolzhna byt' preobrazovana v special'nyj vid, prezh-
de chem ee znachenie mozhet byt'  prisvoeno  polyu, a kogda ona zatem
schityvaetsya iz polya to neobhodimo obratnoe preobrazovanie.  Slovo
preobrazovanie stoilo by zaklyuchit' v kavychki, poskol'ku Bejsik na
samom  dele  ne menyaet sposob predstavleniya  chisla v  pamyati;  on
prosto obrabatyvaet chislo osobym  obrazom.  CHislovye polya trebuyut
dvuh bajtov dlya celyh chisel, chetyreh bajtov - dlya chisel s obychnoj
tochnost'yu i vos'mi bajtov  -  dlya  chisel  s  dvojnoj tochnost'yu. V
tochnosti  takoe  zhe chislo bajt trebuetsya dlya  predstavleniya  etih
chisel v pamyati.   Dlya  preobrazovaniya  ih  v strokovuyu formu nado
ispol'zovat'  funkcii  MKI$, MKS$ i  MKD$,  kotorye  osushchestvlyayut
preobrazovanie  chislo-stroka  dlya  celyh,  veshchestvennyh i chisel s
dvojnoj  tochnost'yu, sootvetstvenno.  Obychno eti funkcii  kombini-


ruyutsya s operatorami RSET ili  LSET,  naprimer, RSET = ACCTNUM$ =
MKI$(X),  gde X - celaya peremennaya, esli polyu ACCTNUM$ bylo otve-
deno dva bajta v operatore FIELD.
   Posle  togo kak polya zapolneny operatorami RSET i LSET, zapis'
zapisyvaetsya na disk s pomoshch'yu operatora  PUT#. PUT #1, 245 pome-
shchaet  dannye v zapis' nomer 245, fajla otkrytogo pod nomerom  #1.
Nomer zapisi mozhet byt' opushchen, v etom sluchae dannye zapisyvayutsya
v  zapis' s nomerom na edinicu bol'she, chem nomer poslednej  zapi-
sannoj zapisi (nachinaya s zapisi 1). Zapisyvaetsya vsya zapis' celi-
kom,  dazhe esli ne vse polya byli zapolneny dannymi.  Otmetim, chto
polya bufera ne ochishchayutsya  pri  vypolenii  operacii  PUT,  poetomu
elementy dannyh, takie kak tekushchaya data, mogut pomeshchat'sya v bufer
tol'ko odin raz, a zatem oni budut  zapisany vo vse zapisi, koto-
rye budut zapisyvat'sya v techenie dannoj sessii. Funkciya LOC vozv-
rashchaet nomer poslednej  zapisannoj  v  fajl zapisi. Esli fajl byl
otkryt pod nomerom #3, to napishite X = LOC(3).
   Funkciya LOF (dlina fajla) vozvrashchaet dlinu fajla v bajtah. Dlya
opredeleniya chisla zapisej,  soderzhashchihsya  v fajle, nado razdelit'
eto znachenie na dlinu zapisi.  Dobavlenie 1 k etomu znacheniyu daet
nomer zapisi, kotoryj nado  ispol'zovat',  chtoby dobavit' k fajlu
novye  zapisi.  Esli fajl byl otkryt pod nomerom #2, a dlina  ego
zapisej ravna 32 bajtam, to  trebuemoe  znachenie  vychislyaetsya kak
RECORDNUM = LOF(2)/32 + 1.
   V sleduyushchem primere fajl pryamogo dostupa otkryvaetsya s  dlinoj
zapisi 24 bajta, prichem zapis' razbita na tri peremennye. Pol'zo-
vatel'  programmy  zaprashivaetsya o soderzhimom vseh treh polej,  a
kogda vse oni vvedeny, to  zapis'  dobavlyaetsya  k fajlu. V stroke
120 vychislyaetsya nachal'nyj nomer zapisi. Otmetim, chto dannye mogut
ne zapisyvat'sya fizicheski na disk  kazhdyj raz pri vypolnenii ope-
ratora PUT. V vyhodnom bufere mogut nakaplivat'sya neskol'ko zapi-
sej, prezhde chem eto budet sdelano.

100 OPEN "R", 1, "A:NEWDATA.DAT", 24  'otkryvaem fajl
110 FIELD 1, 18 AS LASTNAME$, 2 AS AGE$, 4 AS WEIGHT
120 R = LOF(1)/24 + 1         'nomer poslednej zapisi + 1
130 CLS                       'chistim ekran
140 INPUT "Enter name:",N$    'poluchaem imya (stroka)
150 INPUT "Enter age:",A%     'poluchaem vozrast (celoe)
160 INPUT "Enter weight:",W!  'poluchaem ves (veshchestvennoe)
170 RSET LASTNAME$ = N$       'pomeshchaem v pole imya
180 RSET AGE$ = MKI$(A%)      'pomeshchaem v pole vozrast
190 RSET WEIGHT$ = MKS$(W!)   'pomeshchaem v pole ves
200 PUT #1, R                 'zapisyvaem zapis'
210 R = R + 1                 'uvelichivaem schetchik
220 PRINT: PRINT "Do another (y/n)?"  'zapros pol'zovatelya
230 C$ = INKEY$: IF C$ = "" THEN 220  'ozhidaem otveta
240 IF C$ = "y" THEN CLS: GOTO 130    'esli da, to na nachalo
250 CLOSE                     'inache zakryvaem fajl

   Srednij uroven'.

   Kak i vse drugie operacii s fajlami v MS DOS imeetsya dva meto-
da zapisi v fajl pryamogo dostupa, odin s ispol'zovaniem upravlyayu-


shchego bloka fajla, a drugoj s  pomoshch'yu  deskriptora fajla. V oboih
sluchayah  Vy dolzhny sozdat' bufer obmena dannymi, razmer  kotorogo
dolzhen byt' ne men'she, chem razmer zapisi.

Metod upravlyayushchego bloka fajla:
   Otkrojte upravlyayushchij blok  fajla s pomoshch'yu funkcii 0FH i pust'
DS:DX  ukazyvayut na nego.  Posle togo kak fajl  otkryt  pomestite
nomer zapisi dlya  pryamogo  dostupa  v pole zapisi pryamogo dostupa
FCB.  Zatem vyzovite funkciyu 22H preryvaniya 21H, kotoraya  perdast
dannye iz DTA v fajlovyj bufer, sozdannyj pri sozdanii FCB.  Dan-
nye mogut ne byt' nemedlenno zapisany na disk, esli razmer zapisi
men'she chem razmer bufera.  Real'naya zapis' na disk budet proisho-
dit' togda, kogda ocherednoj vyzov funkcii 22H zapolnit bufer.
   Pri  vozvrate iz funkcii 22H AL budet soderzhat' 00, esli obmen
proshel uspeshno. V protivnom sluchae v nem budet 1, esli ne hvataet
prostranstva na diske i 2 - esli oblast' perenosa mala dlya  togo,
chtoby zapisat' odnu zapis' (t.e.  esli razmer bufera, ustanovlen-
nyj sistemoj men'she, chem tot, kotoryj ukazan v FCB).

;---v segmente dannyh
FCB       DB   1, 'NEWDATA    ', 25 DUP (0)
DTA       DB   256 DUP (?)

;---otkryvaem fajl i ustanavlivaem polya FCB
   MOV  AH,0FH          ;nomer funkcii
   LEA  DX,FCB          ;DS:DX ukazyvayut na FCB
   MOV  BX,DX           ;kopiruem smeshchenie dlya FCB
   INT  21H             ;otkryvaem fajl
   MOV  AX,256          ;razmer zapisi
   MOV  [BX]+14,AX      ;pomeshchaem v pole razmera zapisi
   MOV  AX,233          ;nomer zapisi
   MOV  [BX]+33,AX      ;pomeshchaem v pole nomera zapisi
   MOV  AX,0            ;obnulyaem starshij bajt etogo slova
   MOV  [BX]+35,AX      ;
;---perenos dannyh iz DTA v fajl
   MOV  AH,22H          ;nomer funkcii zapisi s pryamym dostupom
   LEA  DX,FCB          ;DS:DX ukazyvayut na FCB
   INT  21H             ;zapisyvaem dannye
   CMP  AL,0            ;proverka na oshibku
   JNE  WRITE_ERROR     ;

;---pozdnee, zakryvaem fajl
   LEA  DX,FCB          ;DS:DX ukazyvayut na FCB
   MOV  AH,10H          ;funkciya zakrytiya fajla
   INT  21H             ;zakryvaem fajl
   CMP  AL,0FFH         ;proverka na oshibku
   JE   CLOSE_ERROR     ;

   CHasto  programma rabotaet srazu s naborom zapisej pryamogo dos-
tupa, peredavaya ih v pamyat' i iz pamyati  kak edinoe celoe. MS DOS
predostavlyaet  special'nuyu  funkciyu dlya etogo  pri  ispol'zovanii
metoda FCB, nazyvaemuyu zapis' bloka  s pryamym dostupom. |to funk-
ciya 28H preryvaniya 21H.  Pri vhode DS:DX dolzhny ukazyvat' na otk-


rytyj FCB, v  kotorom  pole  zapisi  pryamogo  dostupa dolzhno byt'
ravno nomeru pervoj iz zapisyvaemyh zapisej nabora.  |ta  funkciya
sovershenno  analogichna  vysheprivedennomu  primeru.   Edinstvennoe
otlichie  (krome  nomera funkcii) sostoit v tom, chto v  CX  dolzhno
byt' ukazano chislo  zapisej  v  bloke  (ne  putajte eti "bloki" s
blokami po 128 zapisej, s pomoshch'yu kotoryh sistema nahodit trebue-
muyu zapis' - programma mozhet  chitat' lyuboe chislo zapisej, nachinaya
s lyubogo mesta).

   V CX vozvrashchaetsya chislo real'no prochitannyh zapisej.  AL budet
soderzhat' 0, esli vse zapisi  uspeshno  zapisany, 1 - esli ne hva-
taet  prostranstva  na diske, pri etom ne budet zapisana ni  odna
zapis'. V otlichii ot funkcii 22H eta funkciya avtomaticheski uveli-
chivaet polya tekushchej zapisi, tekushchego bloka i zapisi pryamogo  dos-
tupa v FCB, tak chto oni budut  ukazyvat'  na zapis', sleduyushchuyu za
poslednej  prochitannoj.   Otmetim, chto esli pri  vypolnenii  etoj
funkcii ustanovit' CX = 0,  to  razmer  fajla  budet ustanovlen v
sootvetstvii s chislom zapisej, ravnym polyu zapisi pryamogo  dostu-
pa, i takim obrazom mozhno rezervirovat' dlya fajla diskovoe prost-
ranstvo.

Metod deskriptora fajlov:
   Pri ispol'zovanii dlya dostupa metoda deskriptora fajlov siste-
ma ne razlichaet  posledovatel'nye  fajly i fajly pryamogo dostupa.
Vasha programma dolzhna vychislit' poziciyu v fajle, s kotoroj  nachi-
naetsya trebuemaya zapis', i  ustanovit' na nee fajlovyj ukazatel'.
Fajlovyj ukazatel' pozicioniruetsya s pomoshch'yu funkcii 42H preryva-
niya 21H. Pomestite nomer fajla  v  BX, a smeshchenie v fajle v CX:DX
(CX budet soderzhat' starshij bajt znacheniya).  Zatem pomestite v AL
kodovyj nomer ot 0 do 2. Pri AL  =  0, ukazatel' budet ustanovlen
so smeshcheniem CX:DX bajtov otnositel'no nachala fajla; pri AL =  1,
ukazatel' budet ustanovlen so  smeshcheniem CX:DX otnositel'no teku-
shchej  pozicii, a pri AL = 2, ukazatel' budet ustanovlen so  smeshche-
niem CX:DX otnositel'no  konca  fajla  (t.e.   takim obrazom fajl
budet rasshiren).  Otricatel'nye chisla nedopustimy v kachestve sme-
shchenij.  Pri vozvrate DX:AX budut soderzhat' novoe polozhenie ukaza-
telya (starshij bajt v DX).  Esli ustanavlivaetsya flag perenosa, to
proizoshla oshibka. V etom sluchae AX budet soderzhat' 1, esli ukazan
nevernyj kod v AL i 6 - esli ukazan nevernyj nomer fajla.
   Posle  pozicionirovaniya  fajlovogo  ukazatelya  zapis'  pryamogo
dostupa zapisyvaetsya s pomoshch'yu toj zhe funkcii 40H preryvaniya 21H,
kotoraya  ispol'zovalas' dlya zapisi v posledovatel'nyj fajl.   Pri
vhode BX soderzhit nomer fajla, a CX  - chislo bajtov, kotoroe nado
zapisat'.  Pri vozvrate AX budet soderzhat' chislo real'no zapisan-
nyh bajtov. Esli  ono  otlichaetsya  ot  chisla pomeshchennogo v CX, to
veroyatno disk polon (sm. [5.1.4]).  Kak obychno, pri vozniknovenii
oshibki ustanavlivaetsya  flag  perenosa.   V  etom sluchae AX budet
soderzhat'  5  pri  oshibke nakopitelya i 6 - esli  ukazan  nevernyj
nomer fajla.
   Fajlovyj ukazatel' igraet tu zhe  rol' dlya obraza fajla na dis-
ke,  chto DTA dlya obraza fajla v pamyati.  On mozhet sdvigat'sya  kak
ugodno dlya dostupa k razlichnym chastyam fajla.  Bud'te vnimatel'ny,
manipuliruya fajlovym ukazatelem pri rabote s falom pryamogo dostu-


pa, soderzhimoe lyubogo polya lyuboj zapisi mozhet byt' srazu prochita-
no s diska i pomeshcheno v trebuemoe mesto v pamyati.

;---v segmente dannyh
HANDLE        DW    ?           ;nomer fajla
FILEPATH      DB    'A:NEWDATA',0   ;stroka puti k fajlu
REC_BUFFER    DB    30 DUP (?)  ;bufer vyvodimyh zapisej

;---otkryvaem fajl
   MOV  AH,3DH               ;nomer funkcii
   MOV  AL,1                 ;kod otkrytiya dlya zapisi
   LEA  DX,FILEPATH          ;DS:DX ukazyvayut na put'
   INT  21H                  ;otkryvaem fajl
   JC   OPEN_ERROR           ;proverka na oshibku
   MOV  HANDLE,AX            ;sohranyaem nomer fajla

;---vychislyaem poziciyu zapisi i ustanavlivaem fajlovyj ukazatel'
   MOV  AX,30                ;razmer zapisi 30 bajtov
   MOV  CX,54                ;nomer zapisi #54 (55-ya zapis')
   MUL  CX                   ;teper' smeshchenie dlya nee v DX:AX
   MOV  CX,DX                ;pomeshchaem starshee slovo v DX
   MOV  DX,AX                ;pomeshchaem mladshee slovo v CX
   MOV  AL,0                 ;ustanavlivaem ukazatel' na nachalo
   MOV  AH,42H               ;funkciya ustanovki ukazatelya
   MOV  BX,HANDLE            ;nomer fajla
   INT  21H                  ;ustanavlivaem ukazatel'
   JC   POINTER_ERROR        ;proverka na oshibku
;---pishem zapis' s pryamym dostupom
   MOV  AH,40H               ;nomer funkcii
   MOV  BX,HANDLE            ;nomer fajla
   MOV  CX,30                ;razmer zapisi
   LEA  DX,REC_BUFFER        ;DS:DX ukazyvayut na bufer
   INT  21H                  ;pishem zapis'
   JC   WRITE_ERROR          ;proverka na oshibku

   V otlichii ot metoda FCB metod deskriptora fajlov ne predostav-
lyaet special'noj funkcii dlya zapisi  bloka zapisej pryamogo dostu-
pa. Odnako Vashej programme neobhodimo tol'ko vychislit' kolichestvo
bajtov, sostavlyayushchih blok zapisej, kotoroe dolzhno byt' zapisano.




   CHtenie  fajlov pryamogo dostupa yavlyaetsya obratnym processom  po
otnosheniyu k ih zapisi. MS DOS vychislyaet poziciyu v fajle na diske,
zatem  schityvaet zapis' i pomeshchaet ee v pamyat'.  Zatem  programma
dolzhna razdelit' zapis' na polya v tochnosti togo zhe razmera, koto-
ryj byl ispol'zovan pri konstruirovanii zapisi.  Ne zabud'te uda-
lit' simvoly probela, dobavlennye pri zapodnenii polej.  Obsuzhde-
nie zapisi dannyh v fajly pryamogo dostupa [5.4.5] soderzhit infor-
maciyu, kotoraya pomozhet Vam luchshe ponyat' informaciyu dannogo razde-
la.


   Vysokij uroven'.

   Dlya  chteniya  fajla pryamogo dostupa neobhodimo otkryt'  fajl  i
opredelit' polya zapisi, kak  ob®yasneno  v  razdele, otnosyashchemsya k
zapisi v fajly pryamogo dostupa.  Zatem nado ispol'zovat' operator
GET# dlya chteniya opredelennoj zapisi s diska.  GET #1,23 schityvaet
zapis'  nomer #23 iz fajla, otkrytogo pod nomerom #1.  Pri chtenii
zapisi peremennoj, imenovannoj  v  operatore FIELD, avtomaticheski
prisvaivaetsya sootvetstvuyushchee znachenie iz zapisi.  Naprimer, esli
operator FIELD imeet vid  FIELD  1,  20  AS X$, 2 AS Y$, to posle
vypolneniya  operatora GET 1,23 peremennoj X$ budet prisvoeno zna-
chenie pervyh 20-ti bajtov zapisi 23,  a peremennoj Y$ - sleduyushchih
10-ti bajtov.  Operatory,  analogichnye  RSET i LSET dlya vydeleniya
polej dannyh otsutstvuyut.
   V  sluchae  chislovyh  polej, napominaem, chto  oni  dolzhny  byt'
preobrazovany v strokovyj  vid  s  pomoshch'yu  funkcij  MKI$, MKS$ i
MKD$.   Dlya vosstanovleniya ih original'nyh znachenij, s tem  chtoby
nad nimi mozhno bylo provodit' operacii i pechatat' ih, nado preob-
razovat'  eti stroki s pomoshch'yu funkcij CVI, CVS i CVD.   Esli  Y$
soderzhit celoe chislo, to dlya  vypolneniya obratnogo preobrazovaniya
zapishite  Y%  = CVI(Y$), pri etom peremennaya Y%  budet  soderzhat'
znachenie, kotoroe  imela  peremennaya  pered tem kak ona byla spe-
cial'no  obrabotana dlya zapisi v fajl pryamogo dostupa.   Esli  Vy
vyvedete strokovoe znachenie peremennoj, to uvidite, chto eto chislo
v intervale ot 0 do 65535, zakodirovannoe v dva simvola ASCII.
   V  dannom primere otkryvaetsya fajl, sozdannyj v primere punkta
[5.4.5], i vyvoditsya soderzhimoe lyuboj iz zatrebovannyh zapisej:

100 OPEN "A:NEWDATA" AS #1 LEN = 24    'otkryvaem fajl
110 FIELD 1, 18 AS LASTNAME$, 2 AS AGE$, 4 AS WEIGHT$
120 CLS: INPUT "What is the record number";R   'zapros zapisi
130 IF R*24 > LOF(1) THEN BEEP: PRINT"No such record": GOTO 120
140 GET #1,R                     'chitaem zapis' iz fajla
150 PRINT LASTNAME$, CVI(AGE$), CVS(WEIGHT$)   'vyvodim ee
160 PRINT: PRINT "Do another (y/n)?"    'budem povtoryat'?
170 C$ = INKEY$: IF C$ = "" THEN 170    'ozhidaem vvoda
180 IF C$ = "y" OR C$ = "Y" THEN 120    'povtoryaem, esli nado
190 CLOSE                               'inache zakryvaem fajl

   Srednij uroven'.

   Metod FCB dostupa k fajlam imeet  dve funkcii dlya chteniya zapi-
sej s pryamym dostupom. S drugoj storony, metod deskriptora fajlov
ispol'zuet tu zhe funkciyu, chto i dlya  chteniya posledovatel'nyh faj-
lov. Dva metoda dostupa rassmatrivayutsya otdel'no.

Metod FCB:
   Funkciya 21H preryvaniya 21H chitaet odnu zapis' iz fajla pryamogo
dostupa.  Vtoraya funkciya, 27H, chitaet blok posledovatel'nyh zapi-
sej.   Sozdajte upravlyayushchij blok fajla, kak pokazano v [5.3.5]  i
otkrojte ego [5.3.3].  Posle  togo kak FCB otkryt, vvedite v nego
znacheniya polej razmera zapisi (DW po smeshcheniyu 14) i nomera zapisi
pryamogo dostupa (DD  po  smeshcheniyu  33).   Esli DS:DX ukazyvayut na


pervyj  bajt FCB, to mozhno vyzyvat' funkciyu 21H dlya chteniya zapisi
i zapis' budet pomeshchena v payamt', nachinaya s pervogo bajta DTA.
   Esli zapis'  uspeshno  prochitana,  to  v  AL budet vozvrashchen 0.
Odnako pri etom net garantii, chto chtenie proshlo bez oshibok,  pos-
kol'ku nevernyj razmer  zapisi  mozhet  privesti k tomu, chto chasti
prilegayushchih  zapisej  budut schitany, kak budto eto  odna  zapis'.
Esli zaproshena  zapis'  s  nomerom  bol'shim,  chem chislo zapisej v
fajle, to v AL budet vozvrashcheno 1 ili 3.  Esli byl vozvrashchen  kod
3, to byl schitan samyj konec  fajla i byla prochitana chast' zapisi
dannyh. Esli byl vozvrashchen kod 1, to dannye voobshche ne byli schita-
ny.
   Dannyj primer schityvaet odnu zapis' i pomeshchaet ee v DTA:

;---v segmente dannyh
FCB         DB    1,'OLDDATA    ', 25 DUP (0)

;---otkryvaem fajl i ustanavlivaem polya FCB
   MOV  AH,0FH           ;nomer funkcii
   LEA  DX,FCB           ;DS:DX ukazyvayut na FCB
   MOV  BX,DX            ;kopiruem smeshchenie FCB
   INT  21H              ;otkryvaem fajl
   MOV  AX,55            ;razmer zapisi 55 bajtov
   MOV  [BX]+14,AX       ;pomeshchaem v pole razmera zapisi
   MOV  AX,22            ;nomer zapisi dlya chteniya
   MOV  [BX]+33,AX       ;pomeshchaem v pole nomera zapisi
   MOV  AX,0             ;obnulyaem starshee slovo etogo polya
   MOV  [BX]+35,AX       ;
;---perenos dannyh iz fajla v DTA
   MOV  AH,21H           ;nomer funkcii chteniya s pryamym dostupom
   LEA  DX,FCB           ;DS:DX ukazyvayut na FCB
   INT  21H              ;chitaem dannye, pomeshchaya ih v DTA
   CMP  AL,0             ;proverka na oshibku
   JNE  READ_ERROR       ;
;---pozdnee, zakryvaem fajl
   MOV  AH,10            ;nomer funkcii zakrytiya fajla
   LEA  DX,FCB           ;DS:DX ukazyvayut na FCB
   INT  21H              ;zakryvaem fajl

   Dlya  chteniya  bloka posledovatel'nyh zapisej v pamyat'  za  odin
priem nado ispol'zovat' funkciyu 27H preryvaniya 21H. Ee vypolnenie
podgotavlivaetsya  v tochnosti tak zhe, kak i funkcii 21H, za isklyu-
cheniem togo, chto vdobavok CX dolzhen soderzhat' chislo zapisej koto-
rye nado prochitat' za odin priem. Pri vozvrate CX budet soderzhat'
chislo real'no  prochitannyh  zapisej.  Znacheniya  vozvrashchaemye v AL
sovpadayut s temi, kotorye vozvrashchaeyutsya funkciej 21H.  V  otlichii
ot funkcii 21H polya FCB, v  kotoryh hranitsya informaciya o polozhe-
nii zapisi (pole zapisi pryamogo dostupa, tekushchego bloka i tekushchej
zapisi) avtomaticheski uvelichivayutsya, s tem chtoby oni ukazyvali na
sleduyushchuyu neschitannuyu zapis' posle vypolneniya funkcii.
   Otmetim,  chto kak v sluchae chteniya odnoj, tak i v sluchae chteniya
neskol'kih zapisej,  polya  tekushchego  bloka  i  tekushchej zapisi FCB
ustanavlivayutsya po znacheniyu polya zapisi pryamogo dostupa.  Esli Vy


znaete znachenie tekushchego bloka i  tekushchej zapisi, a ne sootvetst-
vuyushchij  nomer zapisi pryamogo dostupa, to ispol'zujte funkciyu  24H
preryvaniya 21H, chtoby ona  prodelala  vychisleniya  za Vas.  U etoj
funkcii net vhodnyh registrov, nado tol'ko, chtoby DS:DX ukazyvali
na otkrytyj FCB.  Pri vozvrate  pole zapisi pryamogo dostupa budet
zapolneno znacheniem, sootvetstvuyushchim ustanovke dvuh drugih polej.

Metod deskriptora fajlov:
   V  predydushchem razdele pokazano, kak pisat' zapisi pryamogo dos-
tupa s pomoshch'yu  metoda  deskriptora  fajlov.  Procedura chteniya iz
fajla  s pryamym dostupom podgotavlivaetsya sovershenno  analogichnym
obrazom, putem  vychisleniya  smeshcheniya  v  fajle, na kotoroe dolzhen
ukazyvat' fajlovyj ukazatel'.  DS:DX dolzhny ukazyvat' na bufer, v
kotoryj budet pomeshchena zapis',  posle chego nado vypolnit' funkciyu
3FH preryvaniya 21H.  Pri vhode CX dolzhen soderzhat' razmer zapisi,
a BX - nomer fajla.

;---v segmente dannyh
HANDLE       DB    ?
FILEPATH     DB    'A:OLDDATA',0
REC_BUFFER   DB    30 DUP(?)

;---otkryvaem fajl
   MOV  AH,3DH          ;nomer funkcii
   MOV  AL,0            ;kod otkrytiya dlya chteniya
   LEA  DX,FILEPATH     ;DS:DX ukazyvayut na put' k fajlu
   INT  21H             ;otkryvaem fajl
   JC   OPEN_ERROR      ;proverka na oshibku
   MOV  HANDLE,AX       ;zapominaem nomer fajla
;---vychislyaem poziciyu zapisi i ustanavlivaem fajlovyj ukazatel'
   MOV  AX,30           ;razmer zapisi
   MOV  CX,54           ;chitaem zapis' #54 (55-yu zapis')
   MUL  CX              ;smeshchenie zapisi v DX:AX
   MOV  CX,DX           ;pomeshchaem starshee slovo smeshcheniya v DX
   MOV  DX,AX           ;pomeshchaem mladshee slovo smeshcheniya v CX
   MOV  AL,0            ;ustanavlivaem ukazatel' na nachalo fajla
   MOV  AH,42H          ;funkciya ustanovki ukazatelya
   MOV  BX,HANDLE       ;nomer fajla
   INT  21H             ;ustanavlivaem ukazatel'
   JC   POINTER_ERROR   ;obrabotka oshibki
;---chitaem zapis' s pryamym dostupom
   MOV  AH,3FH          ;nomer funkcii
   MOV  BX,HANDLE       ;nomer fajla
   MOV  CX,30           ;razmer zapisi
   LEA  DX,REC_BUFFER   ;DS:DX ukazyvayut na bufer dlya zapisi
   INT  21H             ;chitaem zapis'
   JC   READ_ERROR      ;obrabotka oshibki

;---pozdnee, zakryvaem fajl
   MOV  BX,HANDLE       ;nomer fajla
   MOV  AH,3EH          ;funkciya zakrytiya fajla
   INT  21H             ;zakryvaem fajl
   JC   CLOSE_ERROR     ;proverka na oshibku





   MS DOS mozhet  proveryat'  pravil'nost'  proizvodimogo  obmena s
diskom pryamo vo vremya obmena.  Oshibki proishodyat nastol'ko redko,
chto sredstva proverki obychno ne ispol'zuyutsya,  chtoby ne zamedlyat'
obmen s diskom.  Odnako, esli eto neobhodimo, to imeetsya dva spo-
soba proverki. Odin sostoit  vo  vklyuchenii  komandy VERIFY = ON v
fajl  CONFIG.SYS,  kotoryj  avtomaticheski chitaetsya  pri  zagruzke
operacionnoj sistemy.   Vposledstvii, vse diskovye operacii budut
proveryat'sya.  |to edinstvennyj sposob proverki dostupnyj v Bejsi-
ke.  Vtoroj metod sostoit  ispol'zovanii  special'noj funkcii DOS
dlya verifikacii tol'ko kriticheskih diskovyh operacij. Esli proce-
dura verifikacii obnaruzhivaet oshibku,  to ona soobshchaet ob uslovii
kriticheskoj oshibki, kak opisano v [7.2.5].

   Srednij uroven'.

   Funkciya  2EH  preryvaniya 21H  vklyuchaet i  vyklyuchaet  proverku.
Pomestite v AL 1 - dlya  vklyucheniya  verifikacii i 0 - dlya vyklyuche-
niya. DL takzhe dolzhno byt' ravno 0.  Zatem nado vypolnit' preryva-
nie. U etoj funkcii net vyhodnyh registrov.

;---vklyuchenie verifikacii
   MOV  AL,1     ;nomer koda
   MOV  DL,0     ;neobhodimyj vhodnoj registr
   MOV  AH,2EH   ;nomer funkcii
   INT  21H      ;vklyuchaem proverku

   Dlya opredeleniya tekushchego rezhima verifikacii nado vyzvat' funk-
ciyu 54H preryvaniya 21H. U nee net vhodnyh registrov. Pri vozvrate
AL = 1, esli proverka vklyuchena i AL = 0, esli vyklyuchena.




   Diskovye operacii nastol'ko  slozhny, chto imeetsya bol'shoe koli-
chestvo vozmozhnyh oshibok.  Bol'shinstvo diskovyh oshibok obsuzhdayutsya
vmeste s operaciyami, pri kotoryh oni  mogut proishodit'. V dannom
razdele oni sobrany vmeste, chtoby pomoch' Vam pri razrabotke  pro-
cedury obshchego naznacheniya dlya  vosstanovleniya  posle diskovyh oshi-
bok.
   Diskovye  oshibki byvayut dvuh tipov, kotorye my budem  nazyvat'
myagkimi (soft) i zhestkimi  (hard).  Myagkie oshibki voznikayut iz-za
nepravil'nogo  zaprosa na dostup k fajlu: zaproshennyj fajl  mozhet
otsutstvovat' ili diskovoe  prostranstvo  mozhet konchit'sya prezhde,
chem  budet  zapisan ves' fajl.  S drugoj storony, zhestkie  oshibki
voznikayut pri nevernyh posledovatel'nostyah  ili vremennyh nesoot-
vetstvij  pri diskovyh operaciyah, kotorye mogut  byt'  sledstviem
nevernogo vyravnivaniya ili problem s nakopitelem.  V etom sluchae,
luchshe vsego proizvesti sbros diska pered obrabotkoj.


   Vysokij uroven'.

   V  [7.2.5] ob®yasneno kak podgotovit' proceduru obrabotki  oshi-
bok.  Operator ON ERROR  GOSUB  zastavlyaet  programmu  perejti na
proceduru obrabotki oshibki pri vozniknovenii kriticheskoj  oshibki.
Procedura prezhde vsego opredelyaet kodovyj nomer oshibki v Bejsike,
kotoryj dlya diskovyh oshibok mozhet byt' odnim iz sleduyushchih:

   52      Bad file number.  (Nevernyj nomer fajla.) Fajl ne otk-
           ryt pod tem nomerom, k  kotoromu  idet  obrashchenie (#1,
           #2 i t.d.)
   53      File  not  found.  (Fajl ne najden.) Ispol'zuetsya  pri
           vypolnenii operatorov LOAD, KILL, NAME, FILES i OPEN.
   54      Bad file mode.  (Nevernyj rezhim dostupa.) Popytka dos-
           tupa  k fajlu drugim obrazom, po sravneniyu s tem,  dlya
           chego on byl otkryt,  naprimer, popytka zapisi v posle-
           dovatel'nyj fajl, otkrytyj dlya chteniya.
   55      File already open.  (Fajl uzhe otkryt.) Popytka otkryt'
           fajl, kotoryj uzhe otkryt, ili  unichtozhit' (KILL) fajl,
           kotoryj eshche ne zakryt.
   58      File  already exists.  (Fajl uzhe sushchestvuet.)  Popytka
           pereimenovat' fajl  (s  pomoshch'yu  NAME) na imya, kotoroe
           uzhe est' v kataloge.
   61      Disk full.  (Disk polon.) Sm. special'noe obsuzhdenie v
           [5.1.4], otnosyashcheesya k etoj oshibke.
   62      Input past end.   (CHtenie  za  koncom  fajla.) Popytka
           prochitat'  iz posledovatel'nogo fajla bol'she  peremen-
           nyh, chem on soderzhit.   CHtoby izbezhat' etoj oshibki is-
           pol'zujte funkciyu EOF, kak ob®yasneno v [5.4.4].
   63      Bad  record number.  (Nevernyj nomer zapisi.)  Popytka
           prochitat' ili zapisat'  zapis'  s nomerom bol'shim, chem
           chislo zapisej v fajle.
   64      Bad  file  name.  (Nevernoe imya  fajla.)  Ispol'zuetsya
           operatorami KILL, NAME i FILES.
   67      Too many files.   (Slishkom  mnogo  fajlov.) V kataloge
           bol'she net mesta dlya zapisi informacii o fajlah.  Dru-
           goj vozmozhnyj variant sostoit  v tom, chto otkrytie eshche
           odnogo  fajla  privedet k tomu,  chto  budet  prevysheno
           maksimal'no  dopustimoe  chislo  odnovremenno  otkrytyh
           fajlov.

   70      Disk is write-protected. (Disk zashchishchen ot zapisi.)
   71      Disk is not ready. (Disk ne gotov.) Naibolee veroyatno,
           ne zakryt diskovod s disketoj.
   72      Disk media error. (Disk  povrezhden.)  Kak pravilo, eto
           soobshchenie  vydaetsya  pri povrezhdenii  diskety,  odnako
           inogda ono poyavlyaetsya pri sboyah oborudovaniya.
   74      Specified wrong disk  in   RENAME  operation.  (Ukazan
           nevernyj disk v operacii RENAME.)
   75      Path/file  access  error.  (Oshibka  dostupa k  fajlu.)
           Popytka otkryt' podkatalog  ili  metku toma, kak fajl.
           Ili  popytka pisat' v fajl, kotoryj zashchishchen ot zapisi.
           |ta oshibka chashche  vsego  vydaetsya  pri  popytke udalit'


           tekushchij katalog.  Poyavlyaetsya pri operaciyah OPEN, NAME,
           MKDIR, CHDIR i RMDIR.
   76      Path not found.  (Put' ne najden.) Nepravil'no  ukazan
           put' ili ego ne sushchestvuet.   Poyavlyaetsya pri operaciyah
           OPEN, MKDIR, CHDIR i RMDIR.

   Posle togo kak procedura raspoznala oshibku, neobhodimo  infor-
mirovat' ob oshibke pol'zovatelya.  Kogda pol'zovatel' soobshchit, chto
prichina  oshibki ustranena, to operator RESUME posylaet  programmu
nazad na tu stroku, gde proizoshla  oshibka.  Operator RESUME mozhet
soprovozhdat'sya nomerom stroki, poetomu programma mozhet  vernut'sya
k nachalu vsej posledovatel'nosti diskovyh operacij, nezavisimo ot
togo,  v  kakoj  stroke proizoshla oshibka (otmetim, chto  fajly  ne
zakryvayutsya pri vozniknovenii oshibki).  V sleduyushchem primere prog-
ramma  pozvolyaet vosstanovit' situaciyu posle oshibok, svyazannyh  s
perepolneniem diska i zashchitoj ot zapisi:

100 ON ERROR GOSUB 5000         '
 .
 .
600 '''
 .
 .
5000 '''
5010 IF ERR = 61 PRINT "Disk full": GOTO 5100
5020 IF ERR = 70 PRINT "Disk is write protected": GOTO 5100
 .
 .
5100 PRINT "Correct the problem, then strike any key"
5110 C$ = INKEY$: IF C$ = "" THEN 5110
5120 RESUME 600

   Srednij uroven'.

   Funkciya 1 preryvaniya 13H  vozvrashchaet  v AL bajt, dayushchij status
diskovogo nakopitelya. Znachenie ego bitov sleduyushchee:
   bity 0-1   01 = nevernaya komanda, ili, esli bit 3 = 1, to
                   popytka obmena dannymi za granicej 64K
              10 = adresnaya metka ne najdena
              11 = popytka zapisi na zashchishchennyj ot zapisi disk
          2   1  = ukazannyj sektor ne najden
          3   1  = perepolnenie DMA (poterya dannyh pri obmene),
                   ili, esli bit 0 = 1, to popytka obmena dan-
                   nymi za granicej 64K
          4   1  = dannye prochitany neverno, nado povtorit'
          5   1  = oshibka kontrollera
          6   1  = oshibka operacii poiska
          7   1  = net otveta ot nakopitelya (tajm-aut)

   Kazhdaya  iz funkcij obrashcheniya k disku MS DOS ispol'zuet  tol'ko
nekotorye iz vozmozhnyh kodov oshibok, a nekotorye funkcii ne soob-
shchayut ob oshibke.  Odnako vo vseh sluchayah pri vozniknovenii  oshibki


ustanavlivaetsya flag  perenosa.  Esli  proizoshla oshibka, to nomer
koda etoj oshibki vozvrashchaetsya v AX.  Vot kody, otnosyashchiesya k dis-
kovym operaciyam:

   1      Nevernyj nomer funkcii
   2      Fajl ne najden
   3      Put' ne najden
   4      Uzhe otkryto maksimal'no dopustimoe chislo fajlov
   5      Otricanie dostupa (oshibka oborudovaniya)
   6      Nevernyj nomer fajla
  15      Ukazan nevernyj nakopitel'
  16      Popytka udalit' tekushchij katalog
  17      Ne to zhe ustrojstvo
  18      Bol'she net fajlov (pri poiske  v kataloge s ispol'zova-
          niem dzhokerov)

   Vosstanovlenie posle etih "myagkih" oshibok neslozhno.  Nekotorye
preduprezhdayut Vas o programmnyh oshibkah.   Drugie voznikayut iz-za
oshibochnyh dejstvij pol'zovatelya.  Esli zhe ne otvechaet sam nakopi-
tel', to proizoshla kriticheskaya oshibka. V razdele [7.2.5] pokazano
kak napisat' proceduru obrabotki kriticheskih oshibok.
   V MS DOS 3.0 vvedeny rasshirennye kody oshibok.  Oni mogut  byt'
polucheny s pomoshch'yu funkcii 59H preryvaniya 21H, kogda flag pereno-
sa indiciruet vozniknovenie oshibki.  Obsuzhdenie etogo voprosa sm.
v [7.2.5].







   MS DOS mozhet rabotat' s tremya parallel'nymi ustrojstvami (LPT1
- LPT3) i v etoj glave pokazano kak upravlyat' imi. Posledovatel'-
nye  printery upravlyayutsya v tochnosti tak zhe, kak i  parallel'nye,
za isklyucheniem sposoba, kotorym dannye posylayutsya na printer; eta
informaciya  privedena v razdele 1 glavy 7.   Kazhdoe  parallel'noe
ustrojstvo imeet svoj adapter.  Adapter upravlyaetsya tremya regist-
rami  vvoda/vyvoda  i adresa portov etih registrov  razlichny  dlya
kazhdogo adaptera. Oblast' dannyh BIOS soderzhit bazovye adresa dlya
kazhdogo  adaptera.  Bazovyj adres sootvetstvuet  mladshemu  adresu
gruppy  iz  treh  adresov  portov.   Bazovyj  adres  dlya  LPT1  -
0040:0008,  dlya  LPT2 - 0040:000A i t.d.  Kakoj adapter  naznachen
kakomu nomeru LPT - ne opredeleno , kak vidno iz  nizheprivedennoj
tablicy. Po etoj  prichine  programma,  kotraya  pryamo adresuetsya v
parallel'nyj  port, dolzhna vyiskivat' adresa, kotorye on  ispol'-
zuet. Otmetim, chto pri inicializacii bazovomu adresu prisvaivaet-
sya znachenie 0, kogda sootvetstvuyushchij adapter ne ustanovlen.

   Adapter                  Vyhodnyh dannyh  Statusa  Upravleniya

Monohromnaya karta (PC/XT/AT)       3BCH        3BDH      3BEH

Adapter printera PC/XT
Adapter printera PCJr              378H        379H      37AH
Posledovatel'naya/parallel'naya
karta AT (ustanovlennaya kak LPT1)

Posledovatel'naya/parallel'naya      278H        279H      27AH
karta AT (ustanovlennaya kak LPT2)

   Registr  vyhodnyh dannyh - eto tot adres porta, cherez  kotoryj
prohodit kazhdyj bajt dannyh, posylaemyj v printer. Registr statu-
sa  soobshchaet  razlichnuyu informaciyu o  printere;  processor  mozhet
postoyanno oprashivat' ego,  chtoby  raspoznat'  moment, kogda vse v
poryadke i mozhno posylat' dannye.  Registr statusa soobshchaet takzhe,
chto proizoshla oshibka na printere.  Registr upravleniya inicializi-
ruet adapter i upravlyaet vyvodom dannyh. On mozhet takzhe podgotav-
livat' parallel'nyj port  dlya  operacij  preryvaniya,  s tem chtoby
printer  posylal preryvanie k processoru, kogda on gotov k priemu
ocherednogo simvola, ostavlyaya processor  svobodnym dlya drugih del.
Vot znachenie bitov registrov statusa i upravleniya:

Registr upravleniya
   bit  0    0 = normal'naya ustanovka, 1 = vyzyvaet  vyvod  bajta
                 dannyh
        1    0 = normal'naya ustanovka, 1 = avtomaticheskij perevod
                 stroki posle vozvrata karetki
        2    0 = inicializirovat' port printera, 1 = normal'naya
                 ustanovka
        3    0 = otmena vybora printera, 1 = normal'naya ustanovka
        4    0 = preryvanie printera zapreshcheno, 1 = razresheno
      5-7    ne ispol'zuyutsya


Registr statusa
   bit 0-2   ne ispol'zuyutsya
         3   0 = oshibka printera, 1 = net oshibki
         4   0 = printer off-line, 1 = printer on-line
         5   0 = bumaga vstavlena, 1 = net bumagi
         6   0 = printer podtverzhdaet priem simvola, 1 = normal'-
                 naya ustanovka
         7   0 = printer zanyat, 1 = printer svoboden

   Ne imeetsya nikakih osnovanij,  chtoby  lyubaya programma ne imela
proceduru  vosstanovleniya  pri oshibkah, voznikayushchih pri rabote  s
printerom. Horosho napisannaya programma dolzhna nachinat' s proverki
togo, chto printer svyazan s mashinoj (on line). Esli prisoedinen ne
odin printer, to programma dolzhna  pozvolyat' pol'zovatelyu vybrat'
s kakim iz nih on budet rabotat'. Krome togo, eta procedura dolzh-
na vosstanavlivat' situaciyu pri lyubyh  oshibkah printera, pri etom
hotelos'  by,  chtoby ne bylo neobhodimosti  snova  pechatat'  ves'
dokument.




   Programmy dolzhny  inicializirovat' port kazhdogo printera (LPT1
-  LPT3)  pered pervym ispol'zovaniem printera.   Porty  printera
dolzhny takzhe povtorno inicializirovat'sya  posle ustraneniya prichin
oshibki  printera.  Ne putajte inicializaciyu porta printera s ini-
cializaciej samogo printera.  Inicializaciya printera eto vnutren-
nee  delo printera.  Ona proishodit avtomaticheski pri ego vklyuche-
nii i v bol'shinstve sluchaev  printer  ne mozhet byt' povtorno ini-
cializirovan bez ego vyklyucheniya i povtornogo vklyucheniya.  No prog-
ramma mozhet povtorno inicializirovat'  printer, v tom smysle, chto
mogut  byt'  vosstanovleny nachal'nye parametry,  kotorye  printer
ispol'zuet dlya pechati, otmenyaya  vse  special'nye shrifty, ostanovy
tabulyacii  i t.d.  Schitaetsya pravilom horoshego  tona  proizvodit'
takoj sbros printera, kogda programma zavershaet rabotu s nim.
   YAzyki vysokogo urovnya  inicializiruyut  port printera avtomati-
cheski,  no  programmy na yazyke assemblera trebuyut dlya  etoj  celi
korotkuyu proceduru.  S drugoj  storony,  vosstanovlenie nachal'nyh
parametrov pechati trebuetsya vo vseh programmah. Nekotorye printe-
ry, takie kak  novye  |psonovskie  printery,  imeyut  "glavnyj kod
sbrosa", kotoryj privodit k polnomu sbrosu printera. No poskol'ku
ne vse printery imeyut takoj kod, to programma dolzhna predusmatri-
vat'  v  svoej zavershayushchej chasti vosstanovlenie  vseh  izmenennyh
parametrov.  Naprimer, ona mozhet  podat' kody vyklyucheniya kursiva,
vyklyucheniya plotnoj pechati i t.d.  Ne zabud'te vklyuchit' vyzov etoj
procedury v proceduru vyhoda po Ctrl-Break.
   Imejte v vidu, chto na mnogih  printerah  simvoly ne pechatayutsya
do  teh  por, poka ne poluchen kod vozvrata  karetki,  zavershayushchij
stroku (ili do teh por  poka  ne  vvedena  celaya  stroka dannyh).
Simvoly  mogut  spokojno  ozhidat' v bufere printera,  dazhe  posle
togo, kak porodivshaya ih  programma  zavershilas'. Kogda nachinaetsya
novaya  peredacha dannyh na printer, to eti simvoly budut napechata-
ny.  CHtoby izbezhat' etoj  problemy,  ne zabyvajte pochistit' bufer


pered nachalom pechati; a v kachestve pravil horoshego tona,  chistite
bufer takzhe pri zavershenii  programmy.   |to delaetsya posylkoj na
printer koda ASCII 24 (pri etom parametry pechati ne menyayutsya).

   Srednij uroven'.

   Funkciya  1 preryvaniya 17H BIOS inicializiruet port printera  i
vozvrashchaet bajt, dayushchij status porta.  Pomestite v DX nomer porta
-  chislo ot 0 do 2 dlya LPT1 - LPT3, posle chego vyzovite  preryva-
nie.  Bajt statusa printera  (identichnyj  obsuzhdaemomu v [6.1.2])
vozvrashchaetsya v AH.

;---inicializaciya LPT1
   MOV  AH,1       ;funkciya inicializacii printera
   MOV  DX,0       ;LPT1
   INT  17H        ;provodim inicializaciyu

   Nizkij uroven'.

   Renistr  upravleniya  vyvodom kazhdogo adaptera  printera  imeet
bit, kotoryj vyzyvaet inicializaciyu  adaptera. |tot registr imeet
adres porta na 2 bol'she, chem bazovyj adres adaptera.  Napominaem,
chto bazovyj adres dlya LPT1  hranitsya v yachejke 0040:0008, dlya LPT2
-  v 0040:000A i t.d.  Imeyut znachenie tol'ko mladshie 5 bitov  re-
gistra upravleniya vyvodom.  Bit  2 - bit inicializacii printera i
obychno  on ustanavlivaetsya v 1.  Dlya inicializacii adaptera  nado
sbrosit' etot bit v 0 na tysyachu taktov pustogo cikla (3000 dlya AT
ili  na  1/20  sekundy,  ispol'zuya  schetchik  vremeni  sutok  BIOS
[2.1.5]).  V etot moment nuzhno, chtoby byl ustanovlen tol'ko bit 3
(printer  vybran).  Poetomu poshlite v port znachenie 12,  sdelajte
zaderzhku, a zatem poshlite v port obychnoe  (bez preryvanij) neini-
cializonnoe znachenie, kotoroe ravno 8.
   V dannom primere inicializiruetsya LPT1:

;---inicializiruem LPT1
          MOV  DX,ES:[8]    ;schityvaem bazovyj adres v DX
          INC  DX           ;pribavlyaem 2 k bazovomu adresu
          INC  DX           ;
          MOV  AL,12        ;znachenie dlya inicializacii
          OUT  DX,AL        ;nachinaem inicializaciyu
DELAY:    MOV  AX,1000      ;nachalo pustogo cikla
          DEC  AX           ;umen'shaem schetchik
          JNZ  DELAY        ;povtoryaem 1000 raz
          MOV  AL,8         ;obychnoe znachenie dlya registra
          OUT  DX,AL        ;konec inicializacii




   Programma vsegda dolzhna proverit', chto printer svyazan s  mashi-
noj, pered tem, kak poslat' na nego vyvod.  Legko ustanovit', chto
printer  ne gotov, tak kak bit 3 registra statusa printera  usta-
navlivaetsya v 1 v etom sluchae.   No namnogo slozhnee tochno oprede-
lit' pochemu printer ne gotov: vyklyuchen li on, otmenen vybor prin-


tera ili v nem net bumagi. |to proishodit iz-za togo, chto printe-
ry  raznyh proizvoditelej posylayut raznye nabory bitov v  registr
statusa printera, dazhe kogda  oni  nahodyatsya v identichnom sostoya-
nii.   Hotya registr statusa imeet bity, kotorye dolzhny pokazyvat'
eti tri sostoyaniya printera, no v real'nosti  znacheniya bitov mogut
ne  sootvetstvovat' etim usloviyam (bit 3 dolzhen  pokazyvat',  chto
printer vyklyuchen, bit 4 -  chto  otmenen  vybor printera i bit 5 -
chto net bumagi).  Nizheprivedennye znacheniya vozvrashchayutsya v registr
statusa po standartu "|pson", kotoromu obychno sleduet IBM:

   Znachenie         Cepochka bitov          Interpretaciya

     223             11011111           printer gotov
      87             01010111           printer ne gotov
     119             01110111           net bumagi v printere
     247             11110111           printer vyklyuchen

   Registr statusa vvoda imeet adres porta na 1 bol'she, chem bazo-
vyj adres printera.  Bazovyj  adres  dlya  LPT1 hranitsya po adresu
0040:0008,  dlya LPT2 - po adresu 0040:000A i t.d.  Imejte v vidu,
chto esli printer byl vyklyuchen,  to  emu trebuetsya nekotoroe vremya
na  inicializaciyu posle vklyucheniya.  Ne nachinajte pechatat' do  teh
por, poka registr statusa vvoda ne  soobshchit, chto printer svyazan s
mashinoj i gotov k priemu dannyh.

   Vysokij uroven'.

   Dannaya procedura proveryaet svyazan li printer s mashinoj i govo-
rit pol'zovatelyu chto delat', esli net. Ona ispol'zuet znacheniya iz
vysheprivedennoj  tablicy.   Kak uzhe otmechalos', takoj  podhod  ne
podhodit dlya procedury obshchego  naznacheniya, kotoraya budet obsluzhi-
vat'  mnozhestvo raznyh printerov, no on vpolne podhodit, kogda Vy
pishete drajver  dannogo  pechatayushchego  ustrojstva.  Otmetim, chto v
stroke 120 vychislyaetsya dvuhbajtnoe chislo, putem umnozheniya starshe-
go bajta na 256 i dobavleniya  k  mladshemu  bajtu.   Dlya polucheniya
adresa  registra  statusa vvoda k znacheniyu  poluchennogo  bazovogo
adresa dobavlyaetsya 1.

100 '''Poluchaem adres LPT1 i proveryaem gotov li printer
110 DEF SEG = &H40              'ukazyvaem na oblast' BIOS
120 PRTRBASE = PEEK(9)+256*PEEK(8)+1  'adres registra statusa
130 IF INP(PRTRBASE) = 223 THEN 180   'esli printer gotov
140 BEEP                        'inache zvonok i proverki
150 IF INP(PRTRBASE) = 87 THEN LOCATE 1,1: PRINT"Strike the
                               SELECT key": GOTO 150
160 IF INP(PRTRBASE) = 247 THEN LOCATE 1,1: PRINT"Turn the
                                printer on": GOTO 160
170 IF INP(PRTRBASE) <> 223 THEN 170  'zhdem inicializacii
180 '''Teper' printer on-line -- mozhno nachinat' pechat'
190 LPRINT Z$


   Srednij uroven'.

   Dlya polucheniya bajta statusa iz  porta  printera nado ispol'zo-
vat'  funkciyu 2 preryvaniya 17H.  Pri vhode DX soderzhit nomer  LPT
(0-2 dlya LPT1-3). |ta funkciya  sbrasyvaet tri neispol'zuemyh bita
bajta  i delaet operaciyu isklyuchayushchego ILI nad dvumya drugimi, poe-
tomu znacheniya otlichayutsya ot privedennyh vyshe:

   Znachenie         Cepochka bitov          Interpretaciya

     144             10010000           printer gotov
      24             00011000           printer ne gotov
     184             10111000           printer vyklyuchen

I opyat' neobhodimo pomnit', chto eti znacheniya menyayutsya ot printera
k  printeru.   Naibolee obshchuyu informaciyu "vyklyuchen ili ne  gotov"
daet bit 3 statusa ravnyj 0.

   Nizkij uroven'.

   Dannyj primer delaet  samoe  prostoe  -  proveryaem bit on-line
registra statusa.  Dlya polucheniya bajta statusa ispol'zuetsya bazo-
vyj adres LPT1.

;---v segmente
MESSAGE    DB   'Printer not ready - strike any key when OK$'

;---proverka svyazan li printer s mashinoj (on-line)
   MOV  AX,40H               ;ES ukazyvaet na oblast' dannyh BIOS
   MOV  ES,AX                ;
   MOV  DX,ES:[8]            ;poluchaem bazovyj adres
   INC  DX                   ;smeshchenie dlya registra statusa
   IN   AL,DX                ;poluchaem bajt statusa v AL
   TEST AL,1000B             ;proveryaem bit 3
   JNZ  GO_AHEAD             ;esli printer on-line, to vpered
;---pechataem soobshchenie ob oshibke i zhdem nazhatiya klavishi
   MOV  AH,9                 ;funkciya vyvoda stroki
   LEA  DX,MESSAGE           ;DS:DX ukazyvayut na soobshchenie
   INT  21H                  ;pechataem soobshchenie
   MOV  AH,7                 ;funkciya ozhidaniya vvoda
   INT  21H                  ;ozhidaem nazhatiya klavishi (bez eha)
GO_AHEAD:                    ;prodolzhenie programmy




   Proverka oshibok ne dolzhna  prekrashchat'sya  na tom, chto Vy ubedi-
lis', chto printer svyazan s mashinoj.  Oshibki printera mogut prois-
hodit' v lyuboj moment pechati i programma dolzhna byt' gotova voss-
tanovit' situaciyu pri sboyah.  Hotya na printere mogut  proishodit'
samye raznoobraznye  oshibki,  tol'ko  tri  tipa oshibok vozvrashchayut
informaciyu  o sebe v komp'yuter.  |to oshibka "otsutstviya  bumagi",


oshibka "otsutstviya svyazi s  mashinoj" i obshchee soobshchenie "proizoshla
oshibka".  Kak uzhe govorilos' v [6.1.2], ne vse printery  soobshchayut
ob etih oshibkah odinakovym  obrazom, no teoreticheski registr sta-
tusa vvoda ispol'zuet sleduyushchie bity:

   bit 3 = 0 kogda proizoshla oshibka na printere
   bit 4 = 0 kogda printer ne svyazan s mashinoj (off-line)
   bit 5 = 1 kogda konchilas' bumaga na printere

V  chastnosti,  bit 4 mozhet ne ispol'zovat'sya  ukazannym  obrazom.
Registr statusa vvoda imeet adres porta, kotoryj na 1 bol'she, chem
bazovyj adres printera. Bazovyj adres dlya LPT1 hranitsya po adresu
0040:0008, dlya LPT2 - po adresu 0040:000A i t.d.
   Na nizkom urovne, kogda  programma posylaet dannye na printer,
to ona postoyanno obrashchaetsya k bitu 7 etogo registra, chtoby prove-
rit' gotov li printer prinyat' ocherednoj simvol. Neslozhno pri etom
proverit'  pri etom i bit 3, chtoby uznat' o proizoshedshej  oshibke.
Esli proishodit oshibka,  indiciruemaya bitami 4 i 5, to po krajnej
mere bit 3 budet raven 0.  Programma dolzhna postarat'sya proanali-
zirovat' oshibku, a zatem mozhet  poprosit'  pol'zovatelya ispravit'
situaciyu. Otmetim, chto  funkciyu  DOS,  kotoraya vyvodit simvoly na
printer  (funkciya nomer 5 preryvaniya 21H - sm.   [6.3.1]),  mozhno
zastavit' nepreryvno  proveryat'  printer  na oshibku tajmauta pos-
redstvom  komandy MODE.  Pered zagruzkoj programmy,  ispol'zuyushchej
funkciyu 5, nado vvesti komandu  MODE  LPT1: ,,P (eshche luchshe pomes-
tit'  etu  komandu  v fajl AUTOEXEC.BAT, s tem chtoby  ona  vsegda
vypolnyalas' pri zagruzke sistemy).
   Vse eti oshibki privodyat k  tomu,  chto pechat' ostanavlivaetsya i
dolzhny  byt'  predprinyaty kakie-to dejstviya prezhde chem ona  budet
prodolzhena. Slishkom ogorchitel'no dlya pol'zovatelya programmy, esli
bol'shaya porciya dokumenta dolzhna budet pechatat'sya zanovo pri  voz-
niknovenii oshibki na printere.  Tshchatel'noe produmyvanie procedury
vosstanovleniya  po oshibke pozvolit programme vozobnovit' pechat' s
nachala toj stranicy,  na  kotoroj  proizoshla  oshibka.  Neobhodimo
vsegda zapominat' ukazatel'  vyvodimyh  dannyh  pri nachale pechati
novoj  stranicy.  Pri nachale raboty procedury vosstanovleniya  ona
mozhet poprosit' pol'zovatelya  vstavit' novyj list bumagi, a zatem
prodolzhit'  pechat'  s nachala toj stranicy, na  kotoroj  proizoshla
oshibka.

   Vysokij uroven'.

   V Bejsike raspoznayutsya dva oshibochnyh usloviya dlya printera. Kod
oshibki 24 vozvrashchaetsya kogda byl otmenen vybor printera, a kod 27
- kogda printer vyklyuchen ili v nem  otsutstvuet bumaga.  |ti kody
mozhno poluchit' s pomoshch'yu tehniki obnaruzheniya oshibok,  privedennoj
v [7.2.5]. K  sozhaleniyu  effektivno  otlavlivaetsya tol'ko kod 27.
CHtoby  zaregistrirovat'  kod 24 trebuetsya primerno  polminuty,  v
techenie kotoryh programma  zamorozhena.   Ne slishkom polezno pryamo
chitat' registr statusa pered kazhdoj operaciej pechati.  |tot metod
srabotaet pered  nachalom  pechati,  no  nichem  ne pomozhet, esli vo
vremya pechati proizojdet otmena vybora printera. Privodim procedu-
ru obrabotki oshibok printera:


100 ON ERROR GOTO 1000     'ustanavlivaem obrabotku oshibok
 .
 .
1000 '''proveryaem proizoshla li oshibka na printere
1010 IF ERR = 24 OR IF ERR = 27 THEN GOSUB 2000: RESUME
 .
 .
2000 BEEP: LOCATE 1,1: PRINT"Printer not ready"
2010 PRINT "Strike any key when ready"
2020 IF INKEY$ = "" THEN 2020     'ozhidaem vvoda
2030 RETURN

   Srednij uroven'.

   Kogda funkciya 0 preryvaniya 17H  vyvodit  simvol na printer, to
ona  vozvrashchaet bajt statusa printera v AH.  Proveryajte  znachenie
etogo bajta posle posylki kazhdogo  simvola. BIOS slegka modifici-
ruet  bajt statusa.  Obychno bit 0 ne imeet znacheniya, no v  dannom
sluchae  on  ustanavlivaetsya,  kogda  proishodit  oshibka  tajmauta
(printer  ne svyazan s mashinoj).  V sleduyushchem primere  proveryayutsya
dva tipa oshibok: obshchaya  oshibka  "printer  ne gotov" i oshibka "ot-
sutstviya bumagi".  V primere predpolagaetsya, chto v nachale  kazhdoj
stranicy (t.e. posle kazhdogo  perevoda formata) programma zapomi-
naet ukazatel' na nachalo vyvodimyh dannyh, pomeshchaya ego v peremen-
nuyu STARTING_PTR. |to pozvolyaet programme pri vozniknovenii oshib-
ki  povtorit' pechat' s nachala stranicy, a ne s nachala vsego doku-
menta. Konechno printer dolzhen byt' povtorno inicializirovan pered
povtornoj pechat'yu i dolzhny byt' vosstanovleny vse ego  parametry.
(Dannyj primer prosto illyustriruet proverku oshibok - on ni v koej
mere ne yavlyaetsya rabochej proceduroj.)

;---v segmente dannyh
MESSAGE1   DB 'Printer off-line - strike any key when ready$'
MESSAGE2   DB 'Printer out of paper - strike any key when ready$'

;---posylaem simvol i proveryaem na oshibku
NEXT_CHAR:  MOV  AH,0      ;nomer funkcii
   MOV  DX,0               ;vybiraem LPT1
   MOV  AL,[BX]            ;BX ukazyvaet na dannye
   INC  BX                 ;uvelichivaem ukazatel'
   INT  17H                ;posylaem simvol na printer
   TEST AH,00001000B       ;vydelyaem bit 3 (flag oshibki)
   JZ   NEXT_CHAR          ;esli net oshibki, to pechataem dal'she
   TEST AH,00100000B       ;vydelyaem bit 5 (otsutstvie bumagi)
   JZ   OFF_LINE           ;perehod esli s bumagoj vse v poryadke
   MOV  AH,9               ;gotovim pechat' soobshcheniya
   LEA  DX,MESSAGE2        ;DS:DX ukazyvaet na stroku
   INT  21H                ;vyvodim stroku
   JMP  SHORT RECOVER      ;uhodim na vosstanovlenie

OFF_LINE:  MOV  AH,9       ;gotovim pechat' soobshcheniya
   LEA  DX,MESSAGE1        ;DS:DX ukazyvayut na stroku
   INT  21H                ;vyvodim stroku


RECOVER:   MOV  BX,STARTING_PTR  ;vosstanavlivaem ukazatel'
   MOV  AH,0               ;funkciya ozhidaniya vvoda
   INT  16H                ;zhdem
   CALL PRTR_INIT          ;inicializaciya printera
   JMP  NEXT_CHAR          ;nachinaem pechat' s nachala stranicy




   Komp'yutery, osnashchennye neskol'kimi parallel'nymi portami mogut
imet' odnovremenno podsoedinennymi dva ili bolee printerov. Vyvod
mozhet perenapravlyat'sya s odnogo printera na drugoj dvumya sposoba-
mi. Odin sposob sostoit v  tom,  chtoby  ispol'zovat' tol'ko takie
operatory  vyvoda  na pechat', kotorye ukazyvayut na kakoj  printer
nado osushchestvlyat' vyvod.  Vy  mozhete  napisat' takoj kod, kotoryj
pozvolit Vam izmenyat' specifikaciyu.
   Vtoroj  sposob pereklyucheniya printerov sostoit v  ispol'zovanii
vyvoda po umolchaniyu na LPT1, no ukazaniya  drugogo printera, koto-
ryj budet ispol'zovat'sya v kachestve LPT1. |to dostigaetsya izmene-
niem bazovogo  adresa,  otnosyashchegosya  k  LPT1. |tot bazovyj adres
hranitsya v oblasti dannyh BIOS v yachejke 0040:0008.  Pomenyajte ego
s bazovym adresom dlya LPT2 ili 3 (hranyashchimisya v yachejkah 0040:000A
i 0040:000C) i v kachestve LPT1 budet ispol'zovat'sya drugoj  adap-
ter.

   Vysokij uroven'.

   V Bejsike, esli printer byl  otkryt  operatorom OPEN "LPT1" AS
#1,  to chtoby pereklyuchit'sya na drugoj printer nado snachala  napi-
sat' operator CLOSE #1, a zatem otkryt'  drugoj printer s pomoshch'yu
operatora OPEN "LPT2" AS #1.  Vposledstvii vse operatory PRINT #1
budut napravlyat' svoj vyvod  na  vtoroj  printer.   |to izmenenie
trudnee  osushchestvit' v programmah, ispol'zuyushchih operator  LPRINT,
poskol'ku LPRINT po umolchaniyu posylaet ves' vyvod na LPT1. V etom
sluchae Vam neobhodimo pomenyat' bazovye adresa printerov.  Sleduyu-
shchaya programma na  Bejsike  delaet  imenno  eto, pereklyuchaya LPT1 i
LPT2.   Ee  povtornoe ispol'zovanie pereklyuchaet  adresa  obratno,
vozvrashchaya sistemu k pervonachal'noj konfiguracii.

100 DEF SEG = &H40     'ukazyvaem na oblast' dannyh BIOS
110 X = PEEK(8)        'poluchaem mladshij bajt adresa LPT1
120 Y = PEEK(9)        'poluchaem starshij bajt adresa LPT1
130 POKE 8,PEEK(10)    'perenosim mladshij bajt adresa LPT2
140 POKE 9,PEEK(11)    'perenosim starshij bajt adresa LPT2
150 POKE 10,X          'posylaem mladshij bajt LPT1 v LPT2
160 POKE 11,Y          'posylaem starshij bajt LPT1 v LPT2
170 SYSTEM             'vyhodim iz Bejsika

   |ta programma budet  ochen'  kstati,  esli  gotovoe programmnoe
obespechenie ne adresuetsya k nuzhnomu printeru. Ee mozhno otkompili-
rovat' i hranit' na diske, skazhem pod imenem OTHERPRN, posle chego
nado  budet  tol'ko  napechatat' ee imya (v otvet na  zapros  DOS),
chtoby pereklyuchit'sya s printera na  printer. Esli u Vas net trans-
lyatora  s Bejsika, to sozdajte komandnyj fajl OTHERPRN.BAT i  po-


mestite v nego stroku BASIC  OTHERPRN.  Kogda  Vy napechataete OT-
HERPRN, to budet avtomaticheski zagruzhen Bejsik, kotoryj  zagruzit
i  vypolnit  programmu  OTHERPRN.BAS,  posle  chego Vy vernetes' v
operacionnuyu sistemu.  Neobhodimo, pravda, chtoby na diske  imelsya
interpretator Bejsika BASIC.COM.   Pomnite, chto Vy dolzhny ustoyat'
pered iskusheniem ispytat' etu programmu pered tem, kak ona  budet
zapisana na disk, poskol'ku  esli  Vy ee zapustite, to ona sotret
sebya.

   Nizkij uroven'.

   Odin  sposob, kotorym programma na assemblere  mozhet  izmenit'
printer, na kotoryj ona posylaet  dannye, sostoit v ispol'zovanii
dlya pechati tol'ko funkcii 0 preryvaniya 17H [6.3.1].  |ta  funkciya
trebuet, chtoby nomer printera byl pomeshchen v DX. Zavedite peremen-
nuyu  dlya  etogo nomera, s tem chtoby on mog byt'  izmenen v  lyuboj
moment. Vtoraya vozmozhnost'  sostoit v obmene bazovyh adresov LPT1
i LPT2 ili LPT3. Sleduyushchaya programma delaet imenno eto. Kak i vse
korotkie utility, ona dolzhna  pisat'sya v COM forme, kak ob®yasneno
v [1.3.6].

;---obmen bazovymi adresami LPT1 i LPT2
   MOV  AX,40H          ;segment oblasti dannyh BIOS
   MOV  ES,AX           ;ES ukazyvaet na dannye
   MOV  BX,8            ;smeshchenie dlya bazovogo adresa LPT1
   MOV  DX,ES:[BX]      ;sohranyaem bazovyj adres LPT1
   MOV  AX,ES:[BX]+2    ;sohranyaem bazovyj adres LPT2
   MOV  ES:[BX],AX      ;menyaem bazovyj adres LPT2
   MOV  ES:[BX]+2,DX    ;menyaem bazovyj adres LPT1




   Dlya  ustanovki  razlichnyh specifikacij, otnosyashchihsya k  formatu
stranicy, stilyu shrifta i t.p., na  printer posylayutsya special'nye
upravlyayushchie  kody.   |ti kody posylayutsya na printer  kak i  lyubye
drugie dannye. Nekotorye iz nih  eto  prostye odnobajtnye kody iz
chisla pervyh 32-h nabora kodov ASCII. |ti upravlyayushchie kody (pere-
chislennye v [7.1.9]) iniciiruyut takie  prostye dejstviya printera,
kak perevod stroki ili perevod formata (progon stranicy).  Odnako
bol'shinstvo specifikacij pechati ustanavlivaetsya posylkoj Esc-pos-
ledovatel'nostej, v kotoryh odin ili bolee kodovyh bajtov sleduyut
za simvolom Esc, kod kotorogo ASCII 27.  Nachal'nyj kod Esc infor-
miruet  printer,  chto simvol(y) kotoryj sleduet  za  nim  sleduet
interpretirovat' kak komandu, a ne kak dannye. Takie Esc-posledo-
vatel'nosti obychno ne imeyut simvola-ogranichitelya, poskol'ku prin-
ter "znaet" dlinu kazhdoj posledovatel'nosti.   Tol'ko v nekotoryh
sluchayah, kogda posledovatel'nost' mozhet imet' raznuyu dlinu,  tre-
buetsya ogranichivayushchij simvol, v  kachestve kotorogo vsegda ispol'-
zuetsya kod ASCII 0.
   Pochti  vo vseh sluchayah specifikacii ustanovlennye etimi kodami
dejstvuyut do teh por, poka oni ne budut yavno otmeneny. Kak tol'ko
budet  poluchen  kod, naprimer, podcherkivaniya, to ono  budet  osu-
shchestvlyat'sya do teh por, poka ne budet poslan kod otmeny podcherki-
vaniya.  Bufer printera mozhet byt' ochishchen bez otmeny ustanovlennyh
specifikacij.  No esli proizoshla oshibka na printere i printer byl
vyklyuchen i vklyuchen, to neobhodimo  snova ustanavlivat' vse speci-
fikacii.
   Bol'shinstvo kodov ustanavlivayushchih specifikacii printera  pere-
meshany s dannymi, na kotorye oni dejstvuyut.  Naprimer, dannye dlya
slova, kotoroe dolzhno byt' vydeleno zhirnym shriftom, dolzhny  pred-
varyat'sya   Esc-posledovatel'nost'yu,   vklyuchayushchej  zhirnyj shrift, i
zavershat'sya  Esc-posledovatel'nost'yu, vyklyuchayushchej ego.  Poskol'ku
universal'nyj standart na eti  kody  otsutstvuet, to pechat' s is-
pol'zovaniem  moshchnyh vozmozhnostej trebuet, chtoby dlya kazhdogo pod-
derzhivaemogo printera  byli  napisany  drajvery.  Kazhdyj  drajver
preobrazuet instrukcii, generirueiye proceduroj pechati, v  proto-
kol, ispol'zuemyj dannym printerom.
   V assemblere posylka kodov  osushchestvlyaetsya samym obychnym obra-
zom,  no  v Bejsike Vy dolzhny pomnit', chto operatory,  posylayushchie
upravlyayushchie kody (LPRINT ili PRINT#), dolzhny zavershat'sya tochkoj s
zapyatoj.  V protivnom sluchae operatory budut avtomaticheski dobav-
lyat' k posylaemym kodam paru vozvrat karetki/perevod stroki.
   Obsuzhdeniya i primery  posleduyushchih stranic v osnovnom otnosyatsya
k graficheskomu printeru IBM.  Kody, ispol'zuemye etim  printerom,
nastol'ko zhe "standartny", naskol'ko  i lyuboj drugoj protokol.  V
bol'shoj stepeni eto svyazano s tem, chto etot protokol ispol'zuetsya
v epsonovskih printerah (pervye  printery  dlya  IBM PC byli firmy
Epson),  kotorye  sostavlyayut tret' vseh  ispol'zuemyh  printerov.
Upravlyayushchie kody,  ispol'zuemye  printerami  IBM  sravnivayutsya  v
razdele  [6.2.7].  Hotya informaciya, privedennaya v dannom razdele,
mozhet byt' neprimenima k tomu  printeru,  s kotorym Vy rabotaete,
no bol'shinstvo obshchih principov primenimo.





   Printer  vsegda nahoditsya v tekstovom rezhime, do teh por  poka
on special'no ne pereveden v graficheskij rezhim. Komanda, ustanav-
livayushchaya  graficheskij  rezhim, dolzhna soobshchat' kakoe chislo  bajtov
graficheskih dannyh budet  peredano  (no ne bol'she odnoj stroki) i
posle  togo, kak eto chislo bajtov budet interpretirovano kak gra-
ficheskoe izobrazhenie, printer vernetsya v tekstovyj rezhim. Po etoj
prichine net komandy, kotoraya perevodit printer v tekstovyj rezhim.
   CHislo  graficheskih rezhimov u raznyh printerov raznoe.  Vo vseh
sluchayah, za  kodom  ustanavlivayushchim  graficheskij  rezhim sleduyut 2
bajta,  ukazyvayushchie kakoe chislo graficheskih bajtov budet peredano
(snachala mladshij bajt).  CHtoby  vychislit' znachenie etih dvuh baj-
tov,  razdelite chislo bajtov dannyh na 256 i pomestite  rezul'tat
vo vtoroj bajt, a ostatok - v pervyj bajt. Za etimi dvumya bajtami
dolzhny srazu sledovat' bajty dannyh.
   Kazhdyj  bajt opredelyaet cepochku bitov, sootvetstvuyushchih  vos'mi
vertikal'nym tochkam odnoj pozicii v stroke. Mladshij bit (1) soot-
vetstvuet  nizu kolonki, a starshij bit (128) - verhu.   Naprimer,
chtoby napechatat' piramidu, poshlite snachala bajt, u kotorogo usta-
novlen  tol'ko  nizhnij bit, zatem bajt u kotorogo  ustanovleny  2
nizhnih bita i t.d. Posle vos'mogo bajta raspolozhite te zhe bajty v
obratnom  poryadke.   Znachenie pervogo bajta budet 1, vtorogo -  3
(1+2), zatem 7 (1+2+4), zatem 15 (1+2+4+8)  i t.d. Na risunke 6-1
izobrazhena vsya kartina.
   Dlya  pechati  piramidy v Bejsike na  graficheskom  printere  IBM
napishite sleduyushchij kod:

100 LPRINT CHR$(27);CHR$(75);CHR$(15);CHR$(0);CHR$(1);CHR$(3);
        CHR$(7);CHR$(15);CHR$(31);CHR$(63);CHR$(127);CHR$(255);
        CHR$(127);CHR$(63);CHR$(31);CHR$(15);CHR$(3);CHR$(1);

Pervye dva  bajta  perevodyat  printer  v  graficheskij rezhim s 480
tochkami,  sleduyushchie dva - soobshchayut, chto budet peredano 15  bajtov
graficheskih dannyh, a zatem  idet  posledovatel'nost' bajtov dan-
nyh. Konechno to zhe samoe mozhno zaprogrammirovat' umnee, organizo-
vav cikl, v kotorom budut peredavat'sya bajty dannyh. Otmetim, chto
vse problemy v etom sluchae voznikayut, esli ukazannoe chislo bajtov
ne sootvetstvuet chislu  posylaemyh  bajtov.  CHtoby sozdat' probel
mezhdu  graficheskimi figurami vyvedite neskol'ko bajtov s  nulevym
znacheniem.  V Bejsike, kogda v  odnoj  stroke vyvoditsya bol'she 80
bajtov graficheskih dannyh, ne zabud'te predvaritel'no  ustanovit'
"beskonechnuyu"  shirinu  printera.  Dlya  etogo  nado vvesti komandu
WIDTH "LPT1:",255.
   Graficheskij  printer  IBM  imeet chetyrek  graficheskih  rezhima,
kotorye bolee ili menee "standartny". Oni takie:

27,75  480 tochek v stroke. Normal'nyj rezhim. Maksimum 480 bajtov
       dannyh na operator.
27,76  960 tochek v stroke. Udvoennoe gorizontal'noe razreshenie,
       no pechat' vdvoe medlennee (dvojnaya plotnost'). Maksimum
       960 bajtov dannyh na operator.


27,89  960 tochek v stroke, pechat' s normal'noj skorost'yu (dvoj-
       naya plotnost' s vysokoj skorost'yu). Dve tochki, prilegayu-
       shchie po gorizontali, ne mogut byt' napechatany, poskol'ku
       ne budut uspevat' igolki pechatayushchej golovki. Esli delaetsya
       popytka ih napechatat', to vtoraya tochka budet ignorirovat'-
       sya. Maksimum 960 bajtov dannyh na operator.
27,90  1920 tochek v stroke, pechat' vdvoe medlennee (chetvernaya
       plotnost'). Sosednie tochki po gorizontali dolzhny otstoyat'
       po krajnej mere na 3 tochki (t.e. 1 pechataem, 2 propuska-
       em). Maksimum 1920 bajtov dannyh na operator.

V bolee plotnyh rezhimah dve  prilegayushchie  po gorizontali tochki ne
mogut  byt' napechatany.  CHtoby zapolnit' propuski mezhdu  tochkami,
vernite karetku k levomu polyu, nemnogo sdvin'te pechatayushchuyu golov-
ku  vpravo i sdelajte vtoroj prohod, ispol'zuya te zhe dannye.  Vot
sravnenie plotnostej pechati vyzyvaemyh odnimi i temi zhe upravlyayu-
shchimi kodami na raznyh printerah:

  Kody         Graficheskij  Cvetnoj  Kompaktnyj  Proprinter

 27,75          480 tochek     1108      560          480
 27,76          960 tochek     2216       -           960
 27,89          960 tochek     2216       -           960
 27,90         1920 tochek     4432       -          1920

   Cvetnoj  printer unikalen iz printerov IBM tem, chto  on  mozhet
ustanavlivat' masshtabnyj koefficient (aspect ratio) dlya grafiches-
kih izobrazhenij. |tot koefficient otrazhaet raznicu gorizontal'nyh
i vertikal'nyh rasstoyanij mezhdu tochkami. Obychno zhelatelen koeffi-
cient  1:1, poskol'ku v protivnom sluchae trudno provodit'  grafi-
cheskie vychisleniya. No  pri  kopirovanii  graficheskogo ekrana nado
chtoby masshtabnyj koefficient byl takim zhe, kak u displeya.  V  ek-
rannom rezhime umerennogo razresheniya 5 tochek po vertikali zanimayut
tot  zhe  razmer, chto 6 tochek po gorizontali.   |to  sootvetstvuet
masshtabnomu koefficientu 5:6 i  imenno  eto znachenie ispol'zuetsya
po umolchaniyu cvetnym printerom.  Dopuskayutsya tol'ko  koefficienty
1:1 i 5:6.




   Esli  ne  prinimat' vo vnimanie printery, imeyushchie  special'nye
vozmozhnosti grafopostroitelya, to vsya  pechat' osushchestvlyaetsya stro-
kami.   Dazhe  graficheskie izobrazheniya risuyutsya postrochno, hotya  v
etom sluchae net pustyh mest mezhdu  strokami. Kod ASCII 10 - stan-
dartnyj  upravlyayushchij kod perevoda stroki.  Posylka ego na printer
(bez predshestvuyushchego koda Esc) privodit  k tomu, chto bumaga budet
prodvinuta  vpered  na ukazannyj interval.  Obychno, esli  perevod
stroki ne posylaetsya za  kodom  vozvrata  karetki,  to pechatayushchaya
golovka  vozvrashchaetsya k levomu krayu bumagi i mozhno snova pechatat'
na toj zhe stroke.  Odnako mozhno sdelat' tak, chtoby perevod stroki
delalsya avtomaticheski pri kazhdom vozvrate karetki. |tim upravlyayut
pereklyuchateli na printere. |to  zhe  mozhno sdelat' ustanoviv bit 1
registra upravleniya vyvodom (sm. [6.1.0]).  Mnogie printery mogut


vklyuchat'  i  vyklyuchat'  avtomaticheskij  perevod  stroki s pomoshch'yu
upravlyayushchih  kodov 27,53, a nekotorye mogut delat' obratnyj pere-
vod stroki s pmoshch'yu kodov 27,93.
   Po umolchaniyu graficheskij  printer   ispol'zuet interval pechati
ravnyj 1/6 dyujma (t.e.  vyvodyat 6 strok na dyujm) i k etomu rezhimu
vsegda mozhno vernut'sya, posylaya upravlyayushchie  kody 27,50 (eti kody
ispol'zuyutsya  takzhe v sochetanii s kody izmeneniya intervala  mezhdu
strokami, obsuzhdaemymi nizhe).  Dlya etogo printera imeyutsya eshche dva
predopredelennyh  mezhstrochnyh intervala, 1/8 dyujma i 7/72  dyujma.
Sootvetstvuyushchie im upravlyayushchie kody 27,48 i 27,49.
   Vozmozhna i bolee tonkaya gradaciya mezhstrochnyh intervalov.  Gra-
ficheskij printer ispol'zuet tri koda, pozvolyayushchie izmenit' inter-
val na ochen' maluyu velichinu.  Vse tri upravlyayushchih koda ispol'zuyut
2-hbajtnuyu  Esc-posledovatel'nost', za kotoroj sleduet chislo 72-h
ili 216-h dolej dyujma, opredelyayushchih  mezhstrochnyj interval. Verti-
kal'noe  rasstoyanie mezhdu centrami dvuh tochek ravno  1/72  dyujma.
Interval 8/72 dyujma  ne  ostavlyaet  promezhutka  mezhdu strokami (9
strok  na  dyujm).  Standartnyj interval 6 strok na dyujm  zadaetsya
chislom 12/72 dyujma.  Nakonec, 1/216 ravna 1/3 ot 1/72.  Izmenenie
na takuyu velichinu pozvolyaet pechatayushchej golovke slegka  sdvinut'sya
ot centra stroki, s tem chtoby  tochki pri vtorom prohode zapolnili
promezhutki, obespechivaya pechat' bolee vysokogo kachestva.  Vot  eti
Esc-posledovatel'nosti:

   Izmenenie         Esc-posledovatel'nost'

    72-e dyujma       27,65,n (gde n ot 1 do 85)
   216-e dyujma       27,51,n (gde n ot 1 do 255)
   216-e dyujma       27,74,n (gde n ot 1 do 255)

Komandy dlya izmeneniya intervala  v 72-h dyujma ne stanut aktivnymi
do teh por, poka ne vstretitsya vtoroj upravlyayushchij kod: 27,50. Kak
ob®yasnyalos' vyshe, etot  kod  mozhet  takzhe ispol'zovat'sya otdel'no
dlya vosstanovleniya standartnogo intervala v 1/6 dyujma. Esli ranee
byla ispol'zovana komanda 27,65,n, to dlya vosstanovleniya interva-
la v 1/6 dyujma nado poslat' komandu 27,65,12,27,50. Dva upravlyayu-
shchih koda dlya intervalov v 1/216  dyujma  ne identichny.  Pervyj kod
ustanavlivaet,  chto vse posleduyushchie perevody stroki budut  vypol-
nyat'sya s ukazannym intervalom; vtoroj zhe dejstvuet tol'ko na odin
perevod  stroki, a zatem vozvrashchaet interval, kotoryj  dejstvoval
do etogo.

   Sleduyushchaya tablica sravnivaet mezhstrochnye intervaly, vyzyvaemye
odnimi i temi zhe upravlyayushchimi kodami na razlichnyh printerah IBM:

Kody Matrichnyj Graficheskij Cvetnoj Kompaktnyj Strujnyj Romashka  Pro-
      printer   printer    printer  printer    printer         printer

27,48   1/8       1/8        1/8      1/9        1/8     1/8     1/8
27,49   7/72      7/72       6/72     1/9                9/96    7/72
27,50   1/6       1/6        1/6      1/6        1/6     1/6     1/6
27,51             n/216      n/144                               n/216
27,65   n/72      n/72       n/72                        n/72    n/72
27,74             n/216      n/144                               n/216


   Nezavisimo ot togo kak izmenyayutsya mezhstrochnye intervaly, prin-
ter vsegda kontroliruet pryamye i obratnye dvizheniya lista, poetomu
propuski perforacii vsegda delayutsya vovremya.




   Bumaga  na  printere peredvigaetsya komandami perevoda  stroki,
vertikal'noj tabulyacii i perevoda  formata. Ustanovkoj pereklyucha-
telej  na  printere opredelyaetsya budet li  printer  avtomaticheski
perehodit' na novuyu  stranicu  pri  obnaruzhenii  perforacii mezhdu
stranicami.   Esli  perforaciya ne budet propuskat'sya,  to  pechat'
mozhet zavershit'sya pryamo na  vernem  krayu ocherednoj stranicy. Pro-
pusk  perforacii  ostavlyaet po tri pustyh stroki  sverhu i  snizu
kazhdoj stranicy. Na samom dele  printer ne raspoznaet perforaciyu,
vmesto  etogo on schitaet, chto v nachal'nyj moment bumaga vyravnena
na nachalo stranicy i schitaet chislo  perevodov stroki. Mozhno prog-
rammno pereopredelit' ustanovku pereklyuchatelej, posylaya na  prin-
ter upravlyayushchie kody 27,56,  chtoby printer ne delal propuska per-
foracii i 27,57, chtoby delal propusk perforacii.
   Graficheskij  printer ispol'zuet kod,  kotoryj opredelyayut chislo
strok, propuskaemyh mezhdu  stranicami.  |tot kod 27,78,n, gde n -
chislo strok ot 1 do 127.  Naprimer, kod 27,78,10 privedet k tomu,
chto printer budet propuskat' po 10 strok. Esli mezhstrochnyj inter-
val raven 1/6 dyujma, to 11-tidyujmovaya stranica budet soderzhat' 66
strok i posle pechati  kazhdyh  56-ti  strok  printer  budet delat'
propusk  10-ti  strok.  Uzhe Vasha programma  dolzhna  pozabotit'sya,
chtoby v samom nachale prognat'  bumagu  na 5 strok, s tem chtoby 55
strok teksta byli centrirovany na kazhdoj stranice.
   Esli  ispol'zuetsya bumaga, razmer kotoroj otlichaetsya ot  stan-
dartnogo 11-tidyujmovogo, to mozhno  izmenit' dlinu stranicy, s tem
chtoby  propuski  perforacii proishodili v  nuzhnom  meste i  chtoby
perevod formata ustanavlival bumagu v pravil'nuyu poziciyu.  Razmer
stranicy  mozhet  ustanavlivat'sya libo chislom strok  na  stranice,
libo razmerom v dyujmah. CHtoby ustanovit' chislo strok na stranice,
poshlite  kod 27,67,n, gde n - chislo strok.  Ta zhe  posledovatel'-
nost' ispol'zuetsya i  dlya  ustanovki  dliny stranicy v dyujmah, za
isklyucheniem  togo,  chto dlina stranicy zapisyvaetsya v forme  0,n,
gde n mozhet byt' ot 1 do 22 dyujmov. Dlya standartnoj stranicy nado
poslat' komandu 27,67,0,11.




   Pechataemyj  tekst raspredelyaetsya po stranice chastichno za  schet
dvizheniya bumagi [6.2.3], a  chastichno  za schet dvizheniya pechatayushchej
golovki.  Golovka mozhet byt' pozicionirovana v lyuboe mesto, no ne
putem zadaniya ee koordinat. Vmesto etogo ukazyvaetsya ee smeshchenie,
otnositel'no samoj levoj pozicii, kotoruyu ona mozhet dostigat'.  U
printera net datchikov, soobshchayushchih tekushchee polozhenie golovki. Vasha
programma  dolzhna otslezhivat' polozhenie golovki, esli ono  dolzhno
byt' izvestnym. Pri  etom  horoshej  praktikokj  yavlyaetsya nachinat'
pechat' s podachi upravlyayushchego koda 27,60, kotoryj sdvigaet golovku
v samuyu levuyu poziciyu,  ne  delaya  perevoda  stroki  (to zhe samoe
delaet i kod vozvrata karetki).


   Pri  pechati teksta imeetsya neskol'ko sposobov peredvinut'  go-
lovku v nuzhnoe polozhenie.   Ona  mozhet  sdvigat'sya vpravo podachej
odnogo  ili  neskol'kih  simvolvo probela ili  tabulyacii i  vlevo
podachej odnogo ili neskol'kih simvolov  "vozvrat na shag" ili sim-
vola  vozvrata karetki.  Dvizheniya osushchestvlyayutsya nepreryvno -  ne
vosprinimajte ih kak  sootvetstvuyushchie posledovatel'nosti na obych-
noj  pishushchej mashinke.  Do teh por, poka Vasha programma znaet  na-
chal'noe polozhenie pechatayushchej golovki  ona mozhet kombinaciej pere-
vodov  stroki, probelov, tabulyacij i vozvratov na shag  formatiro-
vat' Vash vyvod v  sootvetstvii  s  Vashimi  pozhelaniyami. Printery,
kotorye  umeyut vypolnyat' obratnyj peervod stroki mogut  ispol'zo-
vat'sya i kak grafopostroiteli.
   V graficheskih  rezhimah  vozmozhno  peremeshchenie golovki na malye
doli dyujma.  Pri pechati teksta Vy mozhete vojti v graficheskij  re-
zhim, chtoby dobit'sya raznyh promezhutkov  mezhdu slovami.  K sozhale-
niyu, etot process sushchestvenno zamedlyaet pechat'. Smotrite primer v
punkte [6.3.2].
   Imeetsya special'nyj  kod,  kotoryj  zastavlyaet  golovku vsegda
vozvrashchat'sya  v  krajnyuyu  levuyu poziciyu pered  pechat'yu  ocherednoj
stroki,  otmenyaya  dvunapravlennuyu  pechat'.  Hotya  eto znachitel'no
zamedlyaet pechat', odnako pri etom dostigaetsya bolee tochnoe  pozi-
cionirovanie golovki. |to osobenno polezno pri rabote v grafiches-
kom rezhime.  CHtoby vklyuchit' odnonapravlennuyu pechat' nado  poslat'
kod 27,85,1, a chtoby  vernut'sya  k  dvunapravlennoj  pechati - kod
27,85,0.




   V zavisimosti ot printera mogut ustanavlivat'sya pozicii  gori-
zontal'noj i vertikal'noj  tabulyacii  (graficheskij printer IBM ne
imeet  vertikal'noj tabulyacii).  Gorizontal'nye tabulyacii oprede-
lyayutsya, kak smeshcheniya ot  levogo  kraya,  vyrazhennye  v probelah. V
nekotoryh sluchayah dopuskayutsya do 112 pozicij gorizontal'noj tabu-
lyacii. Analogichno, vertikal'nye tabulyacii opredelyayutsya kak smeshche-
niya  otnositel'no verha stranicy, a izmeryayutsya oni v  mezhstrochnyh
intervalah. Dlya bol'shinstva  printerov  IBM dopuskaetsya ne bol'she
64-h pozicij vertikal'nyh tabulyacij.
   Pervye  dva bajta koda dlya ustanovki gorizontal'noj  tabulyacii
27,68, a dlya ustanovki vertikal'noj  tabulyacii - 27,66. Dlya oboih
tipov tabulyacij dalee idet stroka bajtov, dayushchaya pozicii  tabulya-
cii v vozrastayushchem poryadke. |ta  stroka dolzhna zavershat'sya bajtom
ASCII 0, kotoryj sluzhit ogranichitelem. Dlya ustanovki gorizontal'-
noj tabulyacii v poziciyah 15, 30  i  60 poshlite na printer kod 27,
68, 15, 30, 60, 0. Dlya ustanovki vertikal'noj tabulyacii v strokah
8 i 12 - poshlite kod 27, 66, 8,  12,  0. Otmetim, chto esli razmer
stranicy  otlichaetsya  ot standartnyh 11-ti dyujmov, to  on  dolzhen
byt' ustanovlen pered ustanovkoj  pozicij vertikal'noj tabulyacii.
Vertikal'naya tabulyaciya otmenyaetsya kodom 27,67.
   Otmetim,  chto  bol'shinstvo printerov ne imeyut ustanovki  polej
kak takovoj.  Levoe pole mozhet sozdavat'sya za schet vyvoda tabulya-
cii ili ryada probelov v nachale kazhdoj stroki. Dlya tochnoj ustanov-
ki polej  perejdite  v  graficheskij  rezhim  i vyvedite ryad bajtov
ASCII 0.  Pravoe pole sozdaetsya prosto za schet ogranicheniya  dliny
stroki.





   SHirina stranicy 8 1/2 dyujma  pozvolyaet  napechatat' v stroke do
80-ti  obychnyh  simvolov, esli vse oni imeyut  odinakovuyu  shirinu.
Proporcional'naya pechat' [6.3.3] pozvolyaet  pomestit' v stroke eshche
neskol'ko  simvolov.   S drugoj storony, plotnaya pechat' pozvolyaet
vyvesti v stroke 132 simvola, pechat'  s dvojnoj shirinoj - 40 sim-
volov,  a plotnaya pechat' s dvojnoj shirinoj - 64 simvola.   Imejte
vvidu, chto ispol'zovanie pechati  s  raznoj shirinoj v odnoj stroke
privedet k trudnostyam s formatirovaniem.
   Bol'shinstvo  matrichnyh  printerov predostavlyayut nabor  rezhimov
pechati special'nymi shriftami. Vot perechen' standartnyh vozmozhnos-
tej predostavlyaemyh graficheskim printerom IBM:

Plotnaya pechat':
   Dlya  vklyucheniya rezhima plotnoj pechati nado poslat'  odnobajtnyj
upravlyayushchij kod 15.  Dlya vyklyucheniya etogo rezhima - kod 18.  Stan-
dartnaya  stranica  shirinoj 8 1/2 dyujma pozvolyaet  napechatat'  132
simvola v stroke v etom rezhime.

Pechat' s dvojnoj shirinoj:
   Dlya togo, chtoby printer nachal pechatat'  s dvojnoj shirinoj nado
poslat' na nego upravlyayushchij kod 14.  Rezhim pechati s dvojnoj shiri-
noj neobychen tem, chto printer avtomaticheski vyklyuchaet etot rezhim,
kogda  vstrechaet  simvol  vozvrata karetki ili  perevoda  stroki.
Poskol'ku takoj vid pechati  obychno  ispol'zuetsya dlya odnostrochnyh
zagolovkov, to eto svojstvo udobno.  CHtoby vyklyuchit' etot rezhim v
seredine stroki poshlite kod 20.

Vydelennaya pechat':
   Pri vydelennoj pechati  kazhdyj  simvol  pechataetsya  dva  raza v
odnoj  i  toj zhe pozicii.  |to delaet tochki temnee,  chto  sozdaet
effekt vydeleniya. Skorost' pechati pri etom umen'shaetsya vdvoe. Dlya
vklyucheniya etogo rezhima poshlite kod 27,69. Dlya vyklyucheniya - 27,70.

Pechat' za dva prohoda:
   V  rezhime  pechati  za dva prohoda bumaga sdvigaetsya  na  1/216
dyujma pered vtorym prohodom  pechatayushchej  golovki.  Pri etom polu-
chayutsya bolee zapolnennye bukvy, kotorye k tomu zhe vyglyadyat  yarche.
Skorost' pechati umen'shaetsya vdvoe.   |tot rezhim vklyuchaetsya uprav-
lyayushchim kodom 27,71, a vyklyuchaetsya kodom 27,72.

Pechat' s podcherkivaniem:
   Pechat'  s  podcherkivaniem mozhet vypolnyat'sya  dvumya  sposobami.
Graficheskij printer imeet rezhim podcherkivaniya,  v kotorom podcherk
pechataetsya pod kazhdym simvolom, vklyuchaya probely. Dlya graficheskogo
printera IBM etot rezhim  vklyuchaetsya  kodom 27,45,1, a vyklyuchaetsya
kodom  27,45,0.  Printery, ne imeyushchie rezhima podcherkivaniya  mogut
sdelat' podcherki pri  vtorom  prohode  po  toj zhe stroke, pechataya
simvoly  podcherkivaniya  (ASCII 95) v teh mestah, gde ono nuzhno  i
probely (ASCII 32) vo  vseh  ostal'nyh  pozciciyah.  Vtoroj prohod
dostigaetsya  tem, chto posle pervogo prohoda podaetsya kod vozvrata
karetki bez koda perevoda stroki. Vtoroj prohod ne meshaet printe-
ru pravil'no podschityvat' stroki pri vychislenii razmera stranicy.


Pechat' s verhnimi i nizhnimi indeksami:
   Na graficheskih printerah tekst s verhnimi i nizhnimi  indeksami
szhimaetsya vertikal'no. Dlya pechati verhnego indeksa poshlite uprav-
lyayushchij kod 27,83,0, a dlya pechati nizhnego - 27,83,1.  Mozhno  pryamo
perehodit' ot odnih indeksov  k  drugim.   Dlya  vyklyucheniya pechati
indeksov, s tem, chtoby printer okazalsya na tekushchej stroke poshlite
upravlyayushchij kod 27,84.

   Nekotorye rezhimy ne mogut ispol'zovat'sya v kombinacii s drugi-
mi. Esli Vy hotite ispol'zovat' 4 rezhima odnovremenno, to prokon-
sul'tirujtes' so sleduyushchej tablicej.   V kazhdom iz shesti stolbcov
privedena dopustimaya kombinaciya.

   Kombinaciya           1  2  3  4  5  6

   normal'nyj           H  H
   szhatyj                     H  H
   vydelennyj                       H  H
   za dva prohoda       H     H     H
   s indeksami             H     H     H
   dvojnoj shiriny       H  H  H  H  H  H
   s podcherkivaniem     H  H  H  H  H  H




   V  sleduyushchej tablice sravnivayutsya upravlyayushchie kody dlya printe-
rov IBM.  Ne vsya informaciya otnositel'no kodov tochna (obrashchajtes'
k  dokumentacii  IBM), a v ryade sluchaev unikal'nye kody  opushcheny.
Cel'yu nastoyashchej  tablicy  yavlyaetsya  pokaz  diapazona vozmozhnostej
printerov i ukazanie teh kodov, kotorye mozhno schitat' standartny-
miya. Otmetim, chto kody dlya  pervyh  chetyreh printerov privedeny v
vypuske "Vozmozhnosti i adaptery" (Options and Adapters) iz  serii
tehnicheskih rukovodstv, a kody  dlya ostal'nyh printerov privedeny
v soprovozhdayushchih ih rukovodstv po ekspluatacii.

Kod     Funkciya                    Matrichnyj  Graficheskij  Cvetnoj  Kompaktnyj  Strujnyj  Romashka  Proprinter
                                      printer     printer    printer    printer   printer

  Peremeshchenie bumagi:
  10     perevod stroki                  H           H          H          H         H         H          H
  11     vertikal'naya tabulyaciya          H                      H          H         H         H          H
  12     perevod formata                 H           H          H          H         H         H          H
  13     vozvrat karetki                 H           H          H          H         H         H          H
  27,52  ustanovka nachala stranicy                              H                              H          H
  27,56  ignorirovat' otsutstvie bumagi  H           H
  27,57  otmena ignor. otsutstviya bumagi H           H
  27,66  ustanovka vertikal'nyh tab-cij  H                      H          H         H                    H
  27,66  ochistka vertikal'nyh tab-cij                                                                     H
  27,88  ustanovka propuska perforacii               H          H          H         H                    H
  27,79  otmena propuska perforacii                  H          H          H         H                    H

  Peremeshchenie pechatayushchej golovki:
  8      vozvrat na shag                                         H                    H         H          H
  9      gorizontal'naya tabulyaciya        H           H          H          H         H         H          H
  27,60  sdvig golovki v levyj konec     H           H          H
  27,62  ustanovka indeksa gorizontal'-                                              H
         nogo dvizheniya
  27,68  ustanovka gorizont. tab-cii     H           H          H          H         H         H          H
  27,68  ochistka gorizont. tab-cii                                                                        H
  27,77  avtomaticheskoe formatirovanie                          H
  27,80  vkl./vykl. proporc. pechati                  H                               H
  27,82  vosstan. tab-cij po umolchaniyu                          H          H                   H          H
  27,85  vkl./vykl. odnonapr. pechati                 H          H
  27,88  ustanovka levogo/pravogo polya                          H                              H
  27,100 programmiruemyj probel                                 H
  27,101 programmiruemyj vozvrat na shag                         H


  Mezhstrochnye i mezhsimvol'nye intervaly:
  27,48  mezhstrochnyj interval 1/8 dyujma  H           H          H                    H         H          H
  27,48  mezhstrochnyj interval 1/9 dyujma                                    H
  27,48  mezhstrochnyj interval 7/72 dyujma H           H
  27,49  mezhstrochnyj interval 7/72 dyujma                                                                  H
  27,49  mezhstrochnyj interval 9/96 dyujma                                                       H
  27,49  mezhstrochnyj interval 6/72 dyujma                        H
  27,49  mezhstrochnyj interval 1/9 dyujma                                    H
  27,50  nachat' programmiruemyj pere-    H           H          H
         vod stroki po 27,65
  27,50  mezhstrochnyj interval 1/6 dyujma  H           H          H          H         H         H          H
  27,51  programmiruemyj perevod                     H                                                    H
         stroki (n/216)
  27,51  programmiruemyj perevod                                H
         stroki (n/144)
  27,53  vkl./vykl. avtomatich. pere-                            H          H         H         H          H
         voda stroki
  27,65  programmiruemyj perevod         H           H          H                              H          H
         stroki (n/72)
  27,67  ustanovka dliny stranicy        H           H          H          H         H         H          H
  27,74  programmiruemyj perevod                     H                                                    H
         stroki (n/216)
  27,74  programmiruemyj perevod                                H
         stroki (n/144)
  27,93  obratnyj perevod stroki                                                               H
  27,104 perevod na pol-stroki vpered                                                          H
  27,105 perevod na pol-stroki nazad                                                           H


  Upravlenie shriftami:
  11     rezhim 15 simvolov na dyujm                                                             H
  14     vklyuchenie rezhima dvojnoj shiriny H           H          H          H         H                    H
  15     vklyuchenie plotnoj pechati        H           H          H          H         H                    H
  18     vyklyuchenie plotnoj pechati       H           H                     H         H                    H
  18     rezhim 10 simvolov na dyujm                              H                    H         H
  20     vyklyuch. rezhima dvojnoj shiriny   H           H          H          H         H                    H
  27,45  vkl./vykl. podcherkivaniya                    H          H          H         H         H          H
  27,58  rezhim 12 simvolov na dyujm                              H                              H          H
  27,69  vklyuchenie zhirnoj pechati         H           H          H                                         H
  27,70  vyklyuchenie zhirnoj pechati        H           H          H                                         H
  27,71  vklyuchenie pechati v 2 prohoda    H           H          H                    H                    H
  27,72  vyklyuchenie pechati v 2 prohoda   H           H          H                    H                    H
  27,83  vklyuchenie pechati indeksov                   H          H                    H         H          H
  27,84  vyklyuchenie pechati indeksov                  H          H                    H         H          H
  27,87  vkl./vykl. pechati dvojnoj                   H          H          H         H                    H
         s shirinoj
  27,91  vklyuchenie cvetnogo podcherkiv.                                               H
  27,95  vkl./vykl. overscore                                                                             H

  Ustanovka special'nyh shriftov i cvetov:
  27,54  vybor nabora simvolov 2                     H          H                    H         H          H
  27,55  vybor nabora simvolov 1                     H          H                    H         H          H
  27,61  zagruzka shrifta                                                                       H          H
  27,73  izmenenie kachestva pechati                              H                    H                    H
  27,92  pechatat' upravlyayushchie simvoly                           H                              H          H
  27,94  pechatat' vse simvoly                                   H                              H          H
  27,97  sdvig lenty v konce stranicy                           H
  27,98  vybor 4-j polosy lenty                                 H
  27,99  vybor 3-j polosy lenty                                 H
  27,109 vybor 2-j polosy lenty                                 H
  27,121 vybor 1-j polosy lenty                                 H


  Graficheskie rezhimy:
  27,75  ustanovka rezhima 480 tochek                  H                                                    H
  27,75  ustanovka rezhima 560 tochek                                        H
  27,75  ustanovka rezhima 1108 tochek                            H
  27,76  ustanovka rezhima 960 tochek                  H                                                    H
  27,76  ustanovka rezhima 2216 tochek                            H
  27,89  ustanovka rezhima 960 tochek                  H                                                    H
         s normal'noj skorost'yu
  27,89  ustanovka rezhima 2216 tochek                            H
  27,90  ustanovka rezhima 1920 tochek                 H                                                    H
  27,90  ustanovka rezhima 4432 tochek                            H
  27,91  ustanovka razresheniya/cveta                                                  H
  27,110 ustanovka masshtabnogo koef-nta                         H                    H

  Drugie vozmozhnosti:
  7      zvonok                          H           H          H                              H          H
  20     vyklyuch. rezhima dvojnoj shiriny   H           H          H          H         H                    H
  17     vybor printera                  H                      H                    H         H          H
  19     otmena vybora printera          H                      H                    H         H
  24     ochistka bufera                  H           H          H          H         H         H          H
  27,81  otmena vybora ukazannogo                               H                                         H
         printera




   Posylka dannyh na printer trivial'na v yazykah vysokogo urovnya,
a dlya programmista na yazyke assemblera imeetsya ryad funkcij opera-
cionnoj  sistemy, kotorye delayut zadachu takzhe dostatochno prostoj.
Programmirovanie na nizkom urovne  trebuet bol'she raboty, no zato
predostavlyaet bol'she vozmozhnostej.  Kak pravilo, procedury pechati
nizkogo urovnya  posylayut  simvol  na  printer,  a zatem postoyanno
proveryaet  registr  statusa vvoda porta, k  kotoromu  prisoedinen
printer. Sleduyushchij simvol  posylaetsya tol'ko togda, kogda printer
signaliziruet,  chto  on gotov (printer mozhet ne  pechatat'  simvol
srazu, a zapasat' ego v  svoem  bufere,  do teh por poka ne budet
poluchena celaya stroka simvolov dlya pechati).
   Krome togo, procedury nizkogo urovnya mogut ispol'zovat' prery-
vanie printera ili mogut imitirovat' dejstvie etogo preryvaniya. S
pomoshch'yu  special'nogo  programmirovaniya  mozhno sdelat'  tak,  chto
printer budet  delat'  preryvanie  procenssora,  kogda on gotov k
priemu sleduyushchego simvola.  Procedura obrabotki preryvaniya  posy-
laet sleduyushchij  simvol,  posle  chego  processor  mozhet prodolzhat'
zanimat'sya  svoimi delami.  |tot metod ispol'zuetsya  dlya  fonovoj
pechati (kotoruyu nazyvayut takzhe spulingom).   Poskol'ku fizicheskie
peremeshcheniya  detalej  printera namnogo  medlennee,  chem  skorost'
elektroniki komp'yutera,  to  vyvod  simvolov  na printer zanimaet
lish'  maluyu dolyu processornogo vremeni.  Ispol'zovanie preryvaniya
pozvolyaet ispol'zovat' eto vremya effektivno.
   Pri posylke dannyh na printer trebuetsya sravnitel'no nebol'shie
usiliya,  chtoby dobit'sya uzhasno slozhnogo vyvoda.  Vse slozhnye kar-
tinki, kotorye mozhet vyvodit' printer, dostigayutsya za schet kombi-
nirovaniya tekstovyh i graficheskih dannyh, a takzhe  mnogochislennyh
kodov upravleniya  printerom,  obsuzhdavshihsya  ranee  v etoj glave.
Kombiniruya  v odnoj stroke tekstovyj i graficheskij rezhimy,  mozhno
dobit'sya vyravnivaniya  pravogo  polya  i  proporcional'noj pechati.
Krome  togo lyuboj graficheskij printer mozhet sozdavat' special'nye
simvoly proizvol'nogo vida, a za schet akkuratnogo manipulirovaniya
nadpechatki i mezhstrochnogo intervala mogut vyvodit'sya lyubye simvo-
ly psevdografiki.




   Processor mozhet zanimat'sya  tol'ko  posylkoj dannyh na printer
ili  on  mozhet pechatat' v fonovom rezhime, za  schet  ispol'zovaniya
preryvaniya printera. Vozmozhna i  tret'ya al'ternativa, kogda prog-
ramma  posylaet simvoly na printer cherez opredelennye  intervaly,
chto mozhno rassmatrivat' kak "psevdopreryvanie". |tot metod ne tak
tesno  koordiniruetsya s rabotoj printera, kak nastoyashchee  preryva-
nie, no vo vsyakom sluchae rabota printera ne kritichna ko vremeni.
   Nezavisimo ot togo kak vyvodyatsya dannye, kazhdyj raz na printer
posylaetsya tol'ko 1 bajt dannyh. YAzyki vysokogo urovnya predostav-
lyayut funkcii, kotorye vrode by vyvodyat srazu celye stroki, odnako
na  samom dele eti funkcii razbivayut stroki na otdel'nye simvoly.
Obychno yazyki vysokogo  urovnya  posylayut  na  printer paru vozvrat
karetki/perevod stroki v konce kazhdoj stroki.  S drugoj  storony,
programmy na assemblere  dolzhny  sami  dobavlyat'  etu paru kodov.
Iz-za etogo prihoditsya nemnogo bol'she programmirovat', no  vzamen
Vy poluchaete namnogo bol'shuyu  gibkost', osobenno v otnoshenii pro-
verki oshibok.


   Vysokij uroven'.

   Dlya  posylki dannyh na printer Bejsik predostavlyaet  operatory
LPRINT i PRINT#. LPRINT  ne  trebuet  nikakoj  podgotovki, no dlya
vyvoda operatorom PRINT# Vy dolzhny predvaritel'no otkryt' printer
v tochnosti tak zhe kak i fajl, s pomoshch'yu  operatora OPEN "LPT1" AS
#1  ili  OPEN "LPT3" AS #2.  Operator LPRINT vsegda adresuetsya  k
LPT1, v to vremya kak PRINT# mozhet adresovat'sya k lyubomu printeru.
   Para vozvrat karetki/perevod stroki  avtomaticheski dobavlyaetsya
v  konce  lyubogo operatora LPRINT ili PRINT#, esli tol'ko  on  ne
zavershaetsya tochkoj s zapyatoj.   Dlya  izbezhaniya nenuzhnyh perevodov
stroki  ne  zabyvajte zavershat' posylki lyubyh  upravlyayushchih  kodov
tochkoj s zapyatoj.  To zhe samoe nado delat', esli Vy hotite, chtoby
stroki teksta pechatalis' podryad, prilegayushchie odna k drugoj. Odna-
ko imejte vvidu, chto mnogie  printery ne nachinayut pechatat' do teh
por, poka oni ne poluchat dannye dlya celoj stroki. |to opredelyaet-
sya libo simvolom vozvrat  karetki, libo tem, chto chislo peredannyh
simvolov dostiglo 80-ti (ili drugogo chisla). Ne zabyvajte poslat'
zavershayushchij  kod  vozvrata  karetki,  chtoby  vytolknut' poslednyuyu
porciyu simvolov iz bufera printera.
   Printer  avtomaticheski perehodit na sldeuyushchuyu stroku po dosti-
zheniyu konca stroki.  Po umolchaniyu razmer stroki printera raven 80
simvolam,  no u shirokih printerov eto znachenie mozhet byt' bol'she.
Stroki, vyvodimye v  rezhimah  plotnoj  pechati  ili pechati dvojnoj
shiriny, takzhe menyayut dlinu stroki.  Dlya izmeneniya nomera stolbca,
po dostizhenii kotorogo  golovka  printera  perejdet  na sleduyushchuyu
stroku,  mozhno ustanovit' shirinu printera komandoj WIDTH "LPT1",n
- gde n trebuemyj nomer  stolbca.  Kogda pechataetsya stroka, dlina
kotoroj  bol'she ili ravna shirine printera, to pechatayushchaya  golovka
perehodit na sleduyushchuyu stroku,  chto ekvivalentno vypolneniyu kodov
vozvrat karetki/perevod stroki. |to oznachaet, chto v sluchae, kogda
dlina stroki v tochnosti ravna  shirine  printera, to budet sdelano
dva  perevoda  stroki, esli eta stroka zavershaetsya,  kak  obychno,
paroj vozvrat karetki/perevod stroki.
   Pri graficheskoj pechati printer obychno  ustanavlivayut na besko-
nechnuyu  shirinu.  CHtoby sdelat' eto, nado podat' komandu ustanovki
shiriny, ravnoj 255, WIDTH  "LPT1",255.  Esli Vy zabudete vklyuchit'
etu  komandu, to pri vyvode dlinnyh posledovatel'nostej grafiches-
kih dannyh Bejsik budet  vstavlyat'  paru  vozvrat karetki/perevod
stroki  posle  kazhdyh 80 bajtov dannyh.  |ti  dobavochnye  simvoly
budut vklyuchat'sya v  obshchee  chislo  bajtov  dannyh  dlya graficheskoj
pechati,  poetomu  konec peredavaemyh dannyh budet prosto  opushchen.
   Odin operator LPRINT mozhet soderzhat' neskol'ko  elementov dan-
nyh v razlichnyh vidah.  Informaciya mozhet soderzhat'sya v samom ope-
ratore,  kak  naprimer v LPRINT "The rain in Spain", ili  na  nee
mozhno ssylat'sya po imeni  peremennoj, kak v sluchae X$ = "The rain
in  Spain":  LPRINT X$.  Special'nye simvoly mogut vklyuchat'sya  za
schet ispol'zovaniya funkcii  CHR$.   Upravlyayushchie kody obychno posy-
layutsya  imenno etim sposobom, naprimer, LPRINT CHR$(10)  posylaet
na printer upravlyayushchij kod perevoda  stroki.  CHashche vsego CHR$ is-
pol'zuetsya pri posylke kodov ASCII, kotorye nel'zya vvesti s  kla-
viatury. Lyubye iz perechislennyh tipov dannyh mogut byt' ob®edine-
ny  v odnom operatore.  Esli Vy hotite, chtoby razlichnye  elementy


dannyh pechatalis' podryad, to razdelyajte ih tochkoj s zapyatoj; esli
zhe Vy razdelite ih zapyatymi, to sleduyushchij element budet vyvodit'-
sya so sleduyushchej pozicii tabulyacii.  |to govorit o tom, chto opera-
tor  LPRINT formatiruet pechat' v tochnosti tak zhe, kak eto  delaet
operator PRINT pri vyvode na ekran. Vot neskol'ko primerov:

100 LPRINT S$;" and ";Y$     'kombinaciya treh strok
110 LPRINT X, Y, Z           'vyvod treh chisel
120 LPRINT "The total is "; X  'kombinaciya stroki i chisla
130 LPRINT "The ";CHR$(27);CHR$(45);CHR$(1);"real";
            CHR$(27);CHR$(45);CHR$(0);" thing."
            'podcherkivanie srednego slova

   Operator PRINT# mozhet  ispol'zovat'  te  zhe tipy dannyh, chto i
operator LPRINT, i on takzhe pozvolyaet vklyuchat' neskol'ko  elemen-
tov dannyh v odin operator  i  smeshivat'  razlichnye  tipy dannyh.
Tochki  s zapyatoj i zapyatye dejstvuyut v nem  analogichnym  obrazom.
Vot primery, ekvivalentnye vysheprivedennym:

100 OPEN "LPT1:" AS #2
110 PRINT #2,S$;" and ";Y$
120 PRINT #2,X, Y, Z
130 PRINT #2,"The total is "; X
140 PRINT #2,"The ";CHR$(27);CHR$(45);CHR$(1);"real";
            CHR$(27);CHR$(45);CHR$(0);" thing."

   Srednij uroven'.

   Funkciya 0  preryvaniya  17H  posylaet  odin  simvol na printer.
Pomestite  simvol v AL, a nomer printera v DX.  Pri  vozvrate  AH
budet soderzhat' registr statusa, kotoryj nado postoyanno proveryat'
dlya obnaruzheniya oshibok. V [6.1.3] ob®yasnyaetsya kak eto delat'. Dlya
vyvoda potoka dannyh  ustanovite  ukazatel'  na bufer, soderzhashchij
dannye, i napishite proceduru tipa sleduyushchej:

;---vyvod dannyh na LPT1
   MOV  CX,NUMBER_CHARS    ;CX soderzhit chislo bajt dlya vyvoda
   MOV  DX,0               ;vybiraem LPT1
NEXT_CHAR:  MOV  AH,0      ;funkciya posylki simvola na printer
   MOV  AL,[BX]            ;BX ukazyvaet na bufer dannyh
   INT  17H                ;posylaem simvol
   TEST AH,8               ;proveryaem bit oshibki

   JNZ  PRNTR_ERROR        ;na obrabotku oshibki
   INC  BX                 ;uvelichivaem ukazatel'
   LOOP NEXT_CHAR          ;vyvodim sleduyushchij simvol

   Standartnoe  preryvanie MS DOS dlya vyvoda na printer eto funk-
ciya 5 preryvaniya 21H.  Prosto  pomestite  simvol v DL i vypolnite
preryvanie.  |ta funkciya vsegda vyvodit na LPT1 i u nee net vozv-
rashchaemyh registrov.


;---vyvod dannyh na LPT1
   MOV  AH,5       ;nomer funkcii
   MOV  DL,CHAR    ;gotovim pechataemyj simvol
   INT  21H        ;posylaem ego na printer

   Drugoj sposob vyvoda dannyh na  printer eto funkciya 40H prery-
vaniya  21H.   |to funkciya standartnogo  vyvoda, s  ispol'zovaniem
metoda deskriptora fajlov  dlya  dostupa  k  fajlu  ili ustrojstvu
[5.3.0].  V dannom sluchae eta funkciya ispol'zuet special'nyj pre-
dopredelennyj nomer fajla dlya printera.  |tot nomer #4 i ego nado
pomestit'  v BX.  Funkciya imeet dostup tol'ko k LPT1, poetomu dlya
vyvoda na drugoj  printer  Vam   nado   pomenyat'  bazovye  adresa
[6.1.4].  DS:DX dolzhny ukazyvat' na vyvodimye dannye, a CX soder-
zhat' chislo posylaemyh bajtov. Naprimer:

;---vyvod 120 bajtov dannyh na LPT1
   MOV  AH,40H       ;nomer funkcii
   MOV  BX,4         ;nomer fajla dlya printera
   MOV  CX,120       ;chislo posylaemyh bajtov
   LEA  DX,PRTR_DATA ;DS:DX ukazyvayut na dannye
   INT  21H          ;posylaem dannye
   JC   PRTR_ERROR   ;na obrabotku oshibki

Pri vozvrate ustanovlennyj flag  perenosa  indiciruet oshibku, pri
etom AX budet soderzhat' 5, esli printer ne svyazan s mashinoj i 6 -
esli ukazan nevernyj nomer fajla.  Otmetim, chto pri ispol'zovanii
predopredelennogo nomera fajla nenuzhno otkryvat' ustrojstvo.

   Nizkij uroven'.

   Bajt dannyh posylaetsya na printer, putem posylki ego v registr
vyvodimyh dannyh, adres porta kotorogo  sovpadaet s bazovym adre-
som printera.  Pomnite, chto bazovye adresa dlya LPT1-3 hranyatsya so
smeshcheniyami 8, 10 i  12  v  oblasti  dannyh  BIOS  (nachinayushchejsya s
0040:0000).   Posle togo kak dannye poslany v registr na korotkoe
vremya vklyuchaetsya bit stroba  registra  upravleniya  vyvodom, adres
porta  kotorogo na 2 bol'she, chem dlya registra dannyh.  Nomer bita
stroba raven 0 i on dolzhen byt' ustanovlen tol'ko na ochen' korot-
koe  vremya,  chtoby iniciirovat' peredachu  dannyh,  nahodyashchihsya  v
registre dannyh. Procedura  pechati  mozhet nemedlenno sbrosit' bit
stroba obratno v 0.
   Posle  togo kak bajt dannyh poslan, programma dolzhna  ozhidat',
poka printer ne soobshchit, chto on  gotov  k  priemu sleduyushchego. |to
delaetsya  dvumya sposobami.  Pri gotovnosti printer daet impul's v
bit podtverzhdeniya registra statusa vvoda, adres porta kotorogo na
1 bol'she bazovogo adresa printera. Nomer bita podtverzhdeniya raven
6 i obychno on ustanovlen v 1.   Impul's  podtverzhdeniya sbrasyvaet
etot bit v 0 na dostatochno dolgoe vremya, chtoby programma na yazyke
assemblera mogla uvidet' eto,  esli  ona  postoyanno sledit za re-
gistrom.


   Drugoj  sposob uznat', chto printer gotov k  priemu  sleduyushchego
bajta dannyh sostoit v  nepreryvnoj proverke bita 7 registra sta-
tusa,  kotoryj sbrasyvaetsya v 0, kogda printer zanyat i ustanavli-
vaetsya v 1, kogda on gotov prinyat'  dannye. Esli Vy pishite proce-
duru pechati nizkogo urovnya, kotoraya dolzhna rabotat' v interpreti-
ruemom Bejsike ili drugom ochen' medlennom  yazyke, to nado ispol'-
zovat' etot metod.
   Sleduyushchij primer poluchaet bazovyj adres LPT1 iz oblasti dannyh
BIOS i zatem vyvodit dannye iz  bufera,  na kotoryj ukazyvaet re-
gistr BX.  Programma postoyanno proveryaet registr statusa na zanya-
tost' i odnovremenno  proveryaet  bit  3,  chtoby proverit' nalichie
oshibki na printere.

;---podgotovka
   MOV  AX,40H          ;ES ukazyvaet na oblast' dannyh BIOS
   MOV  ES,AX           ;
   MOV  DX,ES:[8]       ;bazovyj adres LPT1 v DX
   MOV  BX,DATA_START   ;BX ukazyvaet na bufer dannyh
;---posylaem simvol
NEXTCHAR:  MOV  AL,[BX]  ;pomeshchaem simvol v AL
   OUT  DX,AL           ;posylaem simvol
   INC  DX              ;DX budet ukazyvat' na registr
   INC  DX              ;upravleniya vyvodom
   MOV  AL,13           ;cepochka bitov dlya impul'sa stroba
   OUT  DX,AL           ;posylaem signal stroba
   DEC  AL              ;normal'noe ssotoyanie registra
   OUT  DX,AL           ;posylaem ego
;---proverka na oshibku i ozhidanie gotovnosti printera
   DEC  DX              ;DX ukazyvaet na registr statusa
NOT_YET:  IN   AL,DX    ;poluchaem bajt statusa
   TEST AL,8            ;oshibka?
   JNZ  PRTR_ERROR      ;perehod na obrabotku oshibki
   TEST AL,80H          ;printer zanyat?
   JZ   NOT_YET         ;esli zanyat, to nazad
   INC  BX              ;uvelichivaem ukazatel' v bufere dannyh
   DEC  DX              ;DX ukazyvaet na registr dannyh
   JMP  NEXTCHAR        ;idem na pechat' sleduyushchego simvola

   Kogda  ustanovlen  bit  4 upravlyayushchego registra  printera,  to
razresheno preryvanie printera.  Kogda ispol'zuetsya preryvanie, to
programma  ne dolzhna ozhidat' signala gotovnosti ot printera, nep-
reryvno oprashivaya registr  statusa  printera. Vmesto etogo, prog-
ramma  mozhet  poslat' simvol i zanimat'sya drugimi  delami;  kogda
printer budet gotov dlya priema  sleduyushchego  simvola, to on poshlet
signal  podtverzhdeniya (bit 6 registra statusa na  korotkoe  vremya
budet ustanovlen v 1)  i  avtomaticheski  budet vyzvano preryvanie
printera.  Procedura obrabotki preryvaniya poshlet na printer  sle-
duyushchij simvol i  vernet  upravlenie  v programmu, chtoby ona mogla
prodolzhat'  svoyu rabotu, do teh por poka ne proizojdet sleduyushchego
preryvaniya. Kogda vse dannye budut vyvedeny, to preryvanie dolzhno
otklyuchit' sebya. Preryvanie printera vo mnogom analogichno kommuni-
kacionnomu preryvaniyu, kotoroe obsuzhdaetsya v [7.1.8].


   K sozhaleniyu, oborudovanie sdelano tak, chto Vy ne vsegda mozhete
polagat'sya  na  eto svojstvo dlya pervogo adaptera  printera.   Na
nekotoryh adaptorah ono rabotaet, a na drugih net.  Tol'ko v slu-
chae posledovatel'noj/parallel'noj karty AT Vy mozhet polagat'sya na
nego polnost'yu.  Vmesto nego mozhno ispol'zovat' preryvanie tajme-
ra, kak ob®yasneno v [2.1.7].  Ustanovite mikroshemu tajmera  8253

tak,  chtoby  preryvanie  proishodilo  medlennee,  chem skorost', s
kotoroj  printer obrabatyvaet dannye.  Zatem  napishite  proceduru
obrabotki preryvaniya, kotoraya  posylaet na printer ocherednoj sim-
vol  kazhdyj raz, kogda proishodit preryvanie vremeni sutok.   Dlya
togo chtoby obespechit' nadezhnuyu sinhronizaciyu  zastav'te proceduru
proveryat' bit zanyatosti printera registra statusa (bit 7) i  esli
printer eshche zanyat, to pust' procedura ne posylaet simvol.




   Real'noe vyravnivanie pravogo polya zaklyuchaetsya v raspredelenii
probelov, nahodyashchihsya v konce  stroki,  ravnomerno po promezhutkam
mezhdu slovami.  Nekotorye printery imeyut special'nyj rezhim, koto-
ryj avtomaticheski osushchestvlyaet  eto  vyravnivanie.  Takuyu vozmozh-
nost'  imeet  cvetnoj  printer  IBM,  posylka  upravlyayushchego  koda
27,77,0 zastavlyaet elektroniku  printera  interpretirovat' postu-
payushchie dannye i formatirovat' ih. V drugih sluchayah printer dolzhen
menyat' shirinu probelov mezhdu  slovami, pereklyuchayas' v graficheskij
rezhim,  kogda  vyvoditsya simvol probela.  V  graficheskih  rezhimah
shirina probela mozhet izmenyat'sya na razmer do 1/6 razmera simvola.
K  sozhaleniyu, mnogie printery na nekotoroe vremya  ostanavlivayutsya
pri pereklyuchenii mezhdu tekstovym i  graficheskim rezhimami, poetomu
takoj  metod  mozhet okazat'sya slishkom medlennym.   Drugoj  podhod
sostoit vo vstavke obychnyh  simvolov  probela, raspredelyaya ih kak
mozhno bolee ravnomerno po stroke.  Bolee slozhnyj graficheskij pod-
hod opisan nizhe.
   SHagi, kotorye neobhodimo vypolnit' dlya formatirovaniya s vyrav-
nivaniem pravogo polya, sleduyushchie. Vo-pervyh, iz ustanovok formata
stranicy dolzhno byt' vychisleno  chislo  simvolov  v stroke.  Zatem
neobhodimo podschitat' chislo simvolov, zanimaemoe kazhdym iz posle-
dovatel'no vvedennyh slov, vklyuchaya probely mezhdu slovami. Otdel'-
nyj schetchik dolzhen podschityvat' chislo probelov. Kogda obshchaya summa
simvolov prevzojdet 80 (ili tu shirinu  printera, kotoraya ustanov-
lena),  to poslednee slovo dolzhno byt' otbrosheno iz  etoj  summy,
vmeste s predshestvuyushchim emu probelom. CHislo ostavshihsya svobodnymi
pozicij  v stroke umnozhaetsya na 6, poskol'ku kazhdyj simvol  zani-
maet razmer shesti  tochek  po  gorizontali,  a  poluchivsheesya chislo
delitsya na chislo probelov mezhdu slovami.
   Posle pechati kazhdogo slova printer ustanavlivaetsya v grafiches-
kij rezhim 480 tochek v  stroke  i  posylaet  na  printer ryad kodov
ASCII  0.  Kazhdyj takoj bajt sdvigaet pechatayushchuyu golovku na  odnu
tochku vpravo.  Posylaemoe chislo dolzhno byt' ravno shesti dlya obych-
nogo  probela, plyus rezul'tat raspredeleniya pustogo prostranstva.
Nakonec, esli ostatok ot  deleniya  nenulevoj, to nado dobavit' po
odnomu dobavochnomu bajtu k pervym probelam, do teh por poka osta-
tok ne budet ischerpan.


   Dlya  primera  rassmotrim  sluchaj,  kogda  stroka sostoit iz 12
slov,  soderzhashchih 61 bukvu, plyus 11 probelov mezhdu slovami.   |to
ostavlyaet v 80-tisimvol'noj  stroke  8 svobodnyh pozicij. |ti vo-
sem' pozicij, umnozhennye na 6 tochek, sostavlyayut 48 tochek dopolni-
tel'nogo prostranstva stroki.  Poskol'ku v stroke 11 probelov, to
k  kazhdomu iz nih dolzhno byt' dobavleno po 4 dopolnitel'nye tochki
i posle etogo ostanutsya eshche 4 lishnie tochki, kotorye nado dobavit'
po odnoj k pervym chetyrem probelam.  Togda pervye 4 probela budut
imet' razmer 6 tochek normal'nogo  probela, plyus dobavochnye 5, chto
v summe ravno 11.  Ostal'nye probely etoj stroki budut imet' raz-
mer 10 tochek.  CHtoby poslat' eti  dannye  na printer, podgotov'te
snachala kod, posylayushchij na printer 1 bajt ASCII 0, a zatem pomes-
tite ego v cikl, kotoryj  vypolnyajte  stol'ko  raz, skol'ko nuzhno
poslat' takih bajtov. Na ris. 6-2 pokazan etot process.
   V  nizheprivedennom  primere pokazany  osnovy  vyravnivaniya  po
pravomu polyu. Ne zabud'te ob obrabotke special'nyh sluchaev, takih
kak  slovo,  kotoroe  dlinnee stroki (napr., dlinnyj  ryad  tire).
Procedura nuzhdaetsya v modifikacii,  kotoraya pozvolyala by ej imet'
delo so sluchaem, kogda stroka soderzhit vsego neskol'ko slov,  kak
eto byvaet v konce paragrafa.  Ne  pozvolyajte ej raspredelit' eti
slova ravnomerno po vsej shirine stranicy.

   Vysokij uroven'.

   V  dannom primere, BUFFERPTR ukazyvaet na mesto v bufere  dan-
nyh, s kotorogo nachinaetsya sleduyushchaya stroka, vyvodimaya na pechat'.

100 S$ = "This text will be printed with right justification
 using the printer alternately in text modes and graphics modes."
110 STRINGPTR = 1         'ukazatel' v stroke dannyh S$
120 COLUMNS = 1           'schetchik pozicii v stroke
130 SPACES = 0            'schetchik probelov v stroke
140 '''vychislyaem skol'ko slov pomeshchaetsya v stroke
150 C$ = MID$(S$,STRINGPTR,1)  'poluchaem simvol
160 IF C$ <> " " THEN 190  'esli ne probel, to vpered
170 LASTSPACE = COLUMNS   'inache zpominaem poziciyu
180 SPACES = SPACES + 1   'uvelichivaem chislo probelov
190 COLUMNS = COLUMNS+1   'uvelichivaem ukazatel' stolbca
200 STRINGPTR = STRINGPTR + 1  'uvelichivaem ukazatel' dannyh
210 IF COLUMNS = 81 THEN 230   'uhod po koncu stroki
220 GOTO 150              'inache k sleduyushchemu simvolu
230 IF C$ <> " " THEN 270 'esli poslednij ne probel, to uhod
240 COLUMNS = 79          'inache dlina stroki ravna 79
250 SPACES = SPACES - 1   'otnimaem poslednij probel
260 GOTO 340              'idem na vychislenie probelov
270 C$ = MID$(S$,STRINGPTR+1,1)  'proveryaem na konec slova
280 IF C$ <> " " THEN 300 'esli ne probel, to uhod
290 GOTO 340              'inache na vychislenie probelov
300 COLUMNS = COLUMNS - LASTSPACE  'vozvrashchaemsya k koncu slova
310 STRINGPTR = STRINGPTR - COLUMNS + 1  'vozvrashchaem ukazatel'
320 COLUMNS = LASTSPACE - 1  'ubiraem poslednij probel
330 SPACES = SPACES - 1   'umen'shaem chislo probelov


340 '''vychislyaem chislo tochek na probel
350 EXTRASPACES = 80 - COLUMNS  'vychislyaem chislo probelov v konce
360 TOTALSPACES = EXTRASPACES + SPACES   'dobavlyaem k probelam
370 TOTALDOTS = 6*TOTALSPACES   'vychislyaem chislo tochek
380 DOTSPERSPC = TOTALDOTS/SPACES 'poluchaem chislo tochek na probel
390 EXTRADOTS = TOTALDOTS MOD SPACES  'ostatok ot deleniya
400 '''teper' pechataem pervuyu strochku nashego teksta
410 OPEN "LPT1:" AS #1    'otkryvaem printer
420 PRINTPTR = 1          'ukazatel' na nachalo bufera dannyh
430 C$ = MID$(S$,PRINTPTR,1)  'berem simvol
440 PRINTPTR = PRINTPTR + 1   'uvelichivaem ukazatel'
450 IF C$ = " " THEN 500  'esli probel, to na obrabotku probela
460 PRINT #1, C$          'inache pechataem simvol
470 IF PRINTPTR = COLUMNS + 1 THEN 590  'vyhod po koncu stroki
480 GOTO 430              'inache pechataem sleduyushchij simvol
490 '''vot procedura pechati probelov
500 PRINT #1, CHR$(27) + "K";  'perehod v graficheskij rezhim
510 NUMBERDOTS = DOTSPERSPC  'vychislyaem chislo bajtov ASCII 0
520 IF EXTRADOTS = 0 THEN 550  'esli net dobavochnyh tochek, uhod
530 NUMBERDOTS = DOTSPERSPC + 1  'inache dobavlyaem tochku
540 EXTRADOTS = EXTRADOTS - 1  'umen'shaem chislo dobavochnyh tochek
550 PRINT #1, CHR$(NUMBERDOTS);  'posylaem chislo graficheskih bajt
560 PRINT #1, CHR$(0);    '
570 FOR N = 1 TO NUMBERDOTS: PRINT #1, CHR$(0): NEXT
580 GOTO 430              'probel okonchen, idem na sled. simvol
590 PRINT #1, CHR$(13)    'v konce pechataem vozvrat karetki

   Nizkij uroven'.

   Sootvetstvuyushchaya assemblernaya procedura slishkom dlinnaya,  chtoby
privodit' ee zdes'. Ona rabotaet  v tochnosti tak zhe, kak i proce-
dura na Bejsike, za isklyucheniem togo, chto net neobhodimosti zavo-
dit' otdel'nuyu peremennuyu,  chtoby  hranit'  stroku.  Nuzhno prosto
ustanovit' ukazateli na nachalo i konec stroki, kotoruyu nado nape-
chatat' v bufere dannyh.




   Voobshche  govorya,  proporcional'naya pechat' trebuet  special'nogo
printera, kotoryj hranit v PZU informaciyu o shirine kazhdogo simvo-
la.   Cvetnoj  printer IBM imeet rezhim  proporcional'noj  pechati,
kotoryj vklyuchaetsya  posledovatel'nost'yu  27,78,1, a vyklyuchaetsya -
27,78,0.   Programma, kotoraya formatiruet vyvod na takoj printer,
dolzhna znat' informaciyu o shirine kazhdogo  simvola (ee mozhno najti
v dokumentacii). Imeya etu informaciyu, ona mozhet vychislit' skol'ko
slov pomestitsya na odnoj stroke.
   Imejte vvidu, chto nekotorye  matrichnye  printery avtomaticheski
vyvodyat  proporcional'nyj  tekst v rezhime za dva  prohoda.   Esli
slova v stroke razdelyayutsya  dobavochnymi  probelami  v graficheskom
rezhime,  to  printer mozhet perehodit' ko  vtoromu  prohodu  posle
pechati kazhdogo  slova,  vmesto  togo,  chtoby  povtorit' srazu vsyu
stroku. Poskol'ku printery otnositel'no medlenno menyayut napravle-


nie peremeshcheniya pechatayushchej golovki, to v etom sluchae pechat' teks-
ta, vyravnennogo po pravomu krayu, v proporcional'nom rezhime mozhet
zanimat' ochen' mnogo vremeni i  okazyvaetsya neposil'noj noshej dlya
printera.  |ta problema ne voznikaet pri odnonapravlennoj propor-
cional'noj pechati. Otmetim, chto cvetnoj printer IBM mozhet avtoma-
ticheski  kombinirovat' proporcional'nuyu  pechat' s  avtomaticheskim
vyravnivaniem pravogo kraya, chto delaet special'noe programmirova-
nie nenuzhnym.
   Izoshchrennye  programmisty  mogut  zastavit'  lyuboj  graficheskij
printer pechatat'  v  proporcional'nom  rezhime.  Programma  dolzhna
imet'  v pamyati kartinu bitov dlya kazhdogo simvola (sm.  [6.3.4]).
Vmesto togo, chtoby posylat' na  printer  kod ASCII, kotoryj vyzy-
vaet  izobrazhenie  simvola  iz PZU, ispol'zuetsya  dannaya  cepochka
bitov dlya sozdaniya graficheskogo izobrazheniya  stroki teksta. Zatem
vsya nuzhnaya stroka dannyh vyvoditsya na printer v graficheskom rezhi-
me.  |tot podhod rashoduet mnogo  pamyati  na hranenie graficheskih
obrazov  simvolov, odnako on pozvolyaet  polnost'yu  kontrolirovat'
vyvodimoe izobrazhenie.

   Vysokij uroven'.

   V dannom primere vklyuchaetsya  rezhim  proporcional'noj pechati, a
zatem  vyvoditsya pervaya stroka vyhodnyh dannyh programmy.  SHirina
proporcional'nogo shrifta schityvaetsya v massiv FONTWIDTH iz posle-
dovatel'nogo fajla.

100 '''schityvaem massiv shirin shrifta
110 DIM FONTWIDTH(127)     'otvodim massiv dlya shirin
120 OPEN "FONTS" FOR INPUT AS #1  'otkryvaem fajl shirin
130 FOR N = 32 TO 127      'hranyatsya shiriny dlya kodov 32-127
140 INPUT #1, FONTWIDTH(N) 'chitaem shirinu iz massiva
150 NEXT                   'sleduyushchij element
160 '''vychislyaem skol'ko simvolov pomestitsya v stroke
170 CHARPTR = 0            'ukazatel' v bufere
180 LINE$ = ""             'hranit stroku dlya vyvoda
190 LINELENGTH = 0         'schetchik dliny v tochkah
200 WHILE LINELENGTH <480  'dobavlyaem do zapolneniya stroki
210 C$ = PEEK(BUFFERPTR+CHARPTR)  'berem simvol iz bufera dannyh
220 LINELENGTH = LINELENGTH + FONTWIDTH(ASC(C$))
230 LINE$ = LINE$+C$       'dobavlyaem k stroke vyvoda
240 CHARPTR = CHARPTR+1    'uvelichivaem ukazatel'
250 WEND                   'na obrabotku sleduyushchego simvola
260 '''po koncu stroki vozvrashchaemsya k koncu poslednego slova
270 IF C$ = "" THEN 310    'esli poslednij probel, to uhod
280 FOR N = LEN(LINE$) TO 1 STEP -1  'idem nazad ot konca
290 IF MID$(LINE$,N,1) = " " THEN 310 'etot simvol probel?
300 NEXT                   'eschli net, to berem sleduyushchij
310 LINELENGTH = N - 1     'esli da, to predydushchij - poslednij
320 '''inicializiruem proporcional'nuyu pechat' i posylaem dannye
330 LPRINT CHR$(27);CHR$(78);CHR$(1);  'upravlyayushchie kody
340 FOR N = 1 TO LINELENGTH  'dlya kazhdogo simvola
350 LPRINT PEEK(BUFFERPTR+N-1);  'pechataem ego
360 NEXT                   'i idem na sleduyushchij simvol


   Nizkij uroven'.

   Programma na yazyke assemblera dolzhna rabotat' sovershenno  ana-
logichno privedennomu bejsikovskomu  primeru.  Odno iz preimushchestv
assemblera sostoit v tom, chto dlya prosmotra shirin simvolov  mozhno
ispol'zovat' instrukciyu XLAT. Pomestite simvol v AL, DS:DX dolzhny
ukazyvat' na tablicu, posle chego mozhno ispol'zovat' XLAT.  SHirina
simvola budet vozvrashchena v AL:

;---prosmotr shirin simvolov
   LEA  SI,DATA_BUFFER     ;ukazyvaem na bufer dannyh
   LEA  BX,WIDTH_TABLE     ;ukazyvaem na tablicu shirin
   MOV  AL,[SI]            ;poluchaem bajt dannyh
   XLAT WIDTH_TABLE        ;teper' ego shirina v AL




   Bol'shinstvo printerov ne podderzhivayut rasshirennyj nabor simvo-
lov IBM, odnako bol'shinstvo  programm ispol'zuet special'nye sim-
voly psevdografiki.  Ochen' polezno imet' vozmozhnost' pechatat' eti
simvoly i ne tak slozhno eto sdelat'  na lyubom matrichnom printere,
kotoryj  imeet graficheskie vozmozhnosti.  Vmesto togo, chtoby pola-
gat'sya na PZU printera, programma  dolzhna sama sozdavat' eti sim-
voly  i ona dolzhna obrashchat'sya s printerom  opredelennym  obrazom,
chtoby oni byli napechatany na bumage.
   Sama po sebe pechat'  special'nyh  simvolov trivial'na.  Prosto
razbejte simvol na shest' bajtov, cepochka bitov kazhdogo sootvetst-
vuet strukture tochek v kazhdom iz shesti stolbcov tochek, sostavlyayu-
shchih  simvol.   Naprimer, chtoby napechatat'  simvol  gorizontal'noj
dvojnoj cherty, kod ASCII  kotorogo  205, programma dolzhna vyvesti
cepochku bitov 00100100 shest' raz v rezhime 480 tochek v stroke. |to
kolichestvo v  tochnosti  sootvetstvuet  shirine  simvola, poskol'ku
6/480  ravno 1/80 stroki.  CHtoby perevesti printer imenno v  etot
graficheskij rezhim neobhodimo podat' upravlyayushchij kod 27,75.  Zatem
poshlite chislo idushchih vsled graficheskih dannyh, kotoroe peredaetsya
v vide pary bajt, prichem mladshij bajt  pervyj. Nakonec, idut sami
6  bitov  dannyh, kotorye v dannom sluchae  ravny  summe  znachenij
bitov 2 i 5 (4 + 32 = 36). Vsya  posledovatel'nost' celikom vyglya-
dit tak: 27, 75, 6, 0, 36, 36, 36, 36, 36, 36. Dlya bolee vysokogo
razresheniya mogut byt' ispol'zovany bolee tochnye graficheskie rezhi-
my;  voobshche govorya dobavochnye rashody vremeni mashiny nichtozhny, po
sravneniyu so skorost'yu operacij printera.
   Imeetsya  chastnaya problema, kogda simvoly psevdografiki  dolzhny
soprikasat'sya drug s drugom po vertikali.   Obychno printery pecha-
tayut stroku, sostoyashchuyu iz stolbca vos'mi tochek, zatem  spuskayutsya
vniz na vysotu 12  tochek,  ostavlyaya  tem  samym pole razmerom v 4
tochki mezhdu strokami simvolov. Simvoly psevdografiki dolzhny pecha-
tat'sya i v etom pole, a v nekotoryh sluchayah oni zanimayut v vysotu
12 tochek. Poskol'ku bol'shinstvo pechatayushchih golovok imeet tol'ko 8
igolok, to edinstvennym  resheniem  problemy yavlyaetsya pechat' takih
simvolov  za  dva prohoda, prodvigaya bumagu vpered  pered  vtorym
prohodom. V etom sluchae simvol  perevoda stroki (ASCII 10) voobshche
ne ispol'zuetsya.  Vmesto etogo, printer poperemenno delaet inter-


valy vysotoj to v 8, to v 4 tochki.  Pri vtorom prohode chast' igo-
lok budut na tom meste, gde uzhe imeyutsya otpechatannye tochki,  poe-
tomu nado chtoby bity dlya etih igolok byli sbrosheny v 0, chtoby oni
ne rabotali.
   CHtoby  prodvinut' bumagu na vysotu chetyreh tochek nado  poslat'
kod 27, 65, 4, 27, 50, a na  vysotu vos'mi tochek - 27, 65, 8, 27,
50.   Pri  etom vyzyvaetsya avtomaticheskij vozvrat karetki.  V  to
vremya kogda vypolnyaetsya pervyj prohod, gotovitsya vremennaya stroka
teksta, kotoraya budet pechatat'sya pri vtorom prohode.  Esli dannyj
simvol obychnyj, to  v  sootvetstvuyushchuyu  poziciyu  vremennoj vtoroj
stroki  simvolov  nado  pomestit'  probel (ASCII  32).   No  esli
vstrechaetsya special'nyj  graficheskij simvol, kotoryj dolzhen pecha-
tat'sya  v chetyrehtochechnom pole, to nado pomestit' ego kod ASCII v
sootvetstvuyushchyuyu poziciyu vtoroj stroki. Naprimer:

Poziciya simvola   1    2    3    4    5    6    7    8    9   10

Kod ASCII        205  32   98   111  114  105  110  103  32   205
Kod 2-j stroki   205  32   32   32   32   32   32   32   32   205

V pamyati dolzhna hranit'sya  otdel'naya  tablica  cepochek bitov etih
simvolov  dlya  vtorogo prohoda.  Dlya dvojnoj  vertikal'noj  cherty
soderzhimoe tablicy dlya pervogo  prohoda  budet 0, 255, 0, 255, 0,
0,  a dlya vtorogo - 0, 15, 0, 15, 0, 0.  Otmetim, chto vo vtorom i
chetvertom bajte dlya  vtorogo  prohoda  verhnie  4  bita sbrosheny,
chtoby ne bylo nadpechatki.
   Koroche,  kogda nachinaetsya pechat', to v pervuyu  ochered'  prove-
ryaetsya yavlyaetsya li dannyj simvol psedograficheskim, i esli net, to
on  posylaetsya  na pechat', kak obychnyj kod ASCII.   Vo  vremennuyu
stroku, ispol'zuemuyu dlya pechati vtorogo  prohoda vstavlyaetsya pro-
bel.   Zatem obrabatyvaetsya sleduyushchij simvol.  Kogda  vstrechaetsya
simvol psevdografiki, to 6 kodiruyushchih  ego bajtov berutsya iz tab-
licy, printer perevoditsya v graficheskij rezhim dlya vyvoda 6 bajtov
i posylayutsya dannye.  Zatem  printer avtomaticheski vozvrashchaetsya v
tekstovyj  rezhim.  V sootvetstvuyushchuyu poziciyu stroki  dlya  vtorogo
prohoda pomeshchaetsya kod ASCII  etogo  simvola psevdografiki.  |tot
process  prodolzhaetsya do konca stroki, posle chego delaetsya progon
bumagi na vysotu chetyreh tochek.  Pri povtornom prohode nado opyat'
poocheredno  rassmotret' kazhdyj simvol.  Esli eto probel, to  nado
pechatat' simvol probela (t.e.  ne pechatat' nichego, a prosto prod-
vinut'  golovku k sleduyushchemu simvolu).  Esli zhe  eto  graficheskij
simvol, to  nado  najti  sootvetstvuyushchij  emu  dannye dlya vtorogo
prohoda  v  otdel'noj tablice i napechatat' ego takim zhe  obrazom,
kak i pri pervom prohode. Povtorno ispol'zujte stroku dlya vtorogo
prohoda  s kazhdoj pechataemoj strokoj.  Na ris.  6-3 pokazana  eta
procedura.

   Vysokij uroven'.

   V dannom primere tekst razdelen  na dve kolonki, pri etom nep-
reryvnaya  liniya razdelyaet stranicu posredine.  Dlya prostoty pecha-
taetsya tol'ko odna stroka,  odnako  etot  primer mozhet pechatat' i
celuyu stranicu, esli vstavit' cikl FOR/NEXT v strokah 325 i  505.


Dlya demonstracii dvuh podhodov  pri  pervom prohode pechataetsya po
odnomu  simvolu,  v to vremya kak pri  vtorom  prohode  pechataetsya
celaya stroka.

100 '''tablica dannyh dlya pervogo prohoda (tol'ko kody 178 i 179)
110 DATA 0, 0, 255, 0, 0, 0
120 DATA 4, 4, 255, 0, 0, 0
130 '''analogichnaya tablica dlya vtorogo prohoda
140 DATA 0, 0, 15, 0, 0, 0
150 DATA 0, 0, 15, 0, 0, 0
160 '''pomeshchaem pervuyu tablicu v massiv
170 DIM FIRSTPASS$(45)       'opisyvaem massiv
180 FOR N = 1 TO 2           'zapolnyaem ego
190 Y$ = ""                  'Y$ hranit 6 bajtov na simvol
200 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
210 FIRSTPASS$(N) = Y$: NEXT 'pomeshchaem v massiv
220 '''pomeshchaem v massiv vtoruyu tablicu
230 DIM SECONDPASS$(45)      '
240 FOR N = 1 TO 2           '
250 Y$ = ""                  '
260 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
270 SECONDPASS$(N) = Y$: NEXT '
280 '''pechataem tekst sleduyushchej stroki
290 TEXT$ = "Here is one column"+CHR$(179)+"Here is the
             second column"

300 TEMP$ = STRING$(80,32)   'sozdaem stroku dlya 2-go prohoda
310 GRAPH$ = CHR$(27)+CHR$(75)+CHR$(6)+CHR$(0)
320 OPEN "LPT1:" AS #1       'otkryvaem printer
330 FOR N = 1 TO LEN(TEXT$)  'dlya kazhdogo simvola teksta
340 C$ = MID$(TEXT$,N,1)     'berem simvol i proveryaem ego
350 IF C$ < CHR$(128) THEN PRINT #1,C$;: GOTO 400
360 '''predpolagaem, chto vse ostal'nye simvoly - psevdografika
370 PRINT #1,GRAPH$;         'vhodim v graficheskij rezhim
380 PRINT #1,FIRSTPASS$(ASC(C$) - 178);vyvodim 1-j prohod
390 MID$(TEMP$,N) = C$       'marker v stroke 2-go prohoda
400 NEXT
410 '''smeshchaemsya na 8 tochek vniz i delaem vtoroj prohod
420 PRINT #1,CHR$(27)+CHR$(65)+CHR$(4)+CHR$(141);
430 Z$ = ""                  'Z$ soderzhit stroku dlya 2-go prohoda
440 FOR N = 1 TO LEN(TEXT$)  'dlya kazhdogo simvola teksta
450 C$ = MID$(TEMP$,N,1)     'berem simvol i obrabatyvaem ego
460 IF C$ = CHR$(32) THEN Z$ = Z$+" ": GOTO 480
470 Z$ = Z$+GRAPH$+SECONDPASS$(ASC(C$) - 178)
480 NEXT
490 PRINT #1,Z$              'pechataem vsyu stroku srazu
500 PRINT #1,CHR$(10);       'dobavlyaem v konce perevod stroki

   Nizkij uroven'.

   Programma na assemblere  ispol'zuet tot zhe samyj algoritm, chto
i  privedennaya programma na Bejsike.  Kogda  ispol'zuetsya  tol'ko
neskol'ko simvolov, to Vy mozhete  sekonomit' mesto, szhav tablicu,
s  tem  chtoby ih polozhenie v tablice ne bylo  proporcional'no  ih


pozicii v nabore ASCII. Zatem  podgotov'te  nebol'shuyu tablicu in-
deksov s pomoshch'yu instrukcii XLAT, s pomoshch'yu kotoroj mozhno  bystro
iskat' dannye v etoj tablice.




   Damp tekstovogo  ekrana  sdelat'  dostatochno  prosto, esli vse
ispol'zuemye  simvoly soderzhatsya v PZU printera i ni odin iz  nih
ne vyvoditsya so special'nymi atributami, takimi kak podcherkivanie
ili  negativnoe izobrazhenie.  V etom prostejshem sluchae  programme
nuzhno lish' ustanovit' shirinu printera ravnoj 80 simvolam, a zatem
schityvat'  simvoly poocheredno iz videobufera, posylaya ih kak nep-
reryvnyj potok dannyh na printer. Esli v PZU printera otsutstvuyut
special'nye simvoly, takie kak simvoly psevdografiki, to program-
ma dolzhna podgotovit'  svoyu  tablicu  dannyh  dlya etih simvolov i
vyvodit' ih na printer v graficheskom rezhime. Poskol'ku eti simvo-
ly mogut zahodit' v mezhstrochnye intervaly, to mozhet potrebovat'sya
special'noe programmirovanie [6.3.4].
   Kazhdyj  iz special'nyh atributov simvolov sozdaet svoi proble-
my.  Proveryajte atribut  kazhdogo  simvola  pri  schityvanii ego iz
videobufera (v [4.1.3] obsuzhdaetsya znachenie bitov,  sootvetstvuyu-
shchee razlichnym atributam). Kogda  simvol vydelen s pomoshch'yu podcher-
kivaniya  ili povyshennoj intensivnosti, to nado vklyuchat' podcherki-
vanie ili pechat' zhirnym shriftom  na  printere. Odnako esli simvol
vyvoditsya  v negativnom izobrazhenii, to voznikayut te zhe problemy,
chto i s nekotorymi graficheskimi  simvolami:  oblast'  negativnogo
izobrazheniya dolzhna prostirat'sya do verhnego kraya sleduyushchej  stro-
ki. V etom sluchae nado sleduya  ukazaniyam [6.3.4] zapolnit' chernym
vsyu  oblast' pri vtorom prohode.  V zavisimosti ot printera,  Vam
mozhet ponadobit'sya sozdat' special'nuyu  tablicu dannyh dlya vyvoda
simvolov  v  negative, poskol'ku kogda oni budut  pechatat'sya,  to
okruzhayushchie tochki mogut  nahodit'sya  slishkom blizko odna k drugoj,
zatemnyaya izobrazhaemyj simvol. V  etom sluchae ne mozhet byt' i rechi
o  pechati v dva prohoda.  Prostym resheniem problemy s  negativnym
izobrazheniem yavlyaetsya  ispol'zovanie  graficheskogo  rezhima ekrana
dlya vyvoda teksta, a zatem sdelat' damp graficheskogo ekrana.
   Graficheskie dampy sozdayut svoi problemy.  Bajt dannyh printera
sootvetstvuet vos'mi vertikal'nym tochkam, v to vremya kak na ekra-
ne  bajt predstavlyaet 8 gorizontal'nyh tochek.  Poetomu  trebuetsya
procedura  preobrazovaniya,  pokazannaya  na  ris.  6-4. Nado srazu
poluchat' po 8 bajtov pamyati ekrana, vybiraya takie, kotorye  soot-
vetstvuyut oblasti tochek 8*8.  Zatem  nado ispol'zovat' logicheskie
operacii dlya perestanovki bitov, kak pokazano v primerah.
   Imejte  vvidu,  chto bol'shinstvo matrichnyh  printerov  iskazhayut
ekrannoe izobrazhenie.  |to  proishodit potomu, chto oni ispol'zuyut
masshtabnyj koefficient 1:1, v to vremya kak ekran ispol'zuet koef-
ficient 5:6 (masshtabnyj koefficient sravnivaet chislo gorizontal'-
nyh  tochek na dyujm s chislom vertikal'nyh tochek na dyujm).   Tochnee
govorya, iskazhenie izobrazheniya na samom dele voznikaet iz-za massh-
tabnogo koefficienta ekrana, poskol'ku programmy dolzhny special'-
no menyat' dannye dlya  izobrazheniya,  chtoby  ono vyglyadelo tak, kak
nam hochetsya (naprimer, izobrazhenie okruzhnosti na ekrane sozdaetsya
vyvodom na nego  ellipsa).   Kogda  dannye  s ekrana vyvodyatsya na


printer, to eti iskazhenie dolzhny obrashchat'sya.  Nekotorye grafiches-
kie printery imeyut special'nye  rezhimy,  v kotoryh mozhno vyvodit'
kopiyu  ekrana bez iskazheniya, a cvetnoj printer IBM  mozhet  menyat'
masshtabnyj koefficient v lyubom iz svoih graficheskih rezhimov.

   Vysokij uroven'.

   Privodimaya procedura na  Bejsike delaet kopiyu tekstovogo ekra-
na, ignoriruya special'nye atributy:

 10 OPEN "LPT1:" AS #1          'otkryvaem printer
 20 DEF SEG = &HB000            'ukazyvaem na videobufer
 30 PRINT #1,CHR$(13)           'sdvigaem golovku vlevo
 40 FOR G = 0 TO 3998 STEP 2    'dlya kazhdogo bajta bufera
 50 PRINT #1,CHR$(PEEK(G));     'chitaem ego i vyvodim na printer
 60 NEXT                        'obrabatyvaem sleduyushchij bajt

Perebroska cepochek bitov dlya graficheskogo dampa trebuet v Bejsike
slishkom mnogo vremeni.  Pomestite  v massiv (zdes', BYTE$) vosem'
bajtov,  otvechayushchih  oblasti ekrana 8*8 tochek.   Sozdajte  vtoroj
massiv (VERTICAL$) i  obnulite  ego  elementy, a zatem poocheredno
perebrasyvajte bity elementov etih massivov sleduyushchim obrazom:

500 FOR M = 0 TO 7       'dlya kazhdogo bita
510 FOR N = 0 TO 7       'dlya kazhdogo bajta
520 X = ASC(BYTES(N))    'poluchaem znachenie bajta
530 Y = 2*(7 - M)        'maska dlya odnogo vklyuchennogo bita
540 Z = X AND Y          'proverka etogo bita v bajte
550 IF Z <> 0 THEN VERTICAL$(M) = CHR$(ASC(VERTICAL$(M) OR 2*N)
                         'esli on vklyuchen, to ustanavlivaem bit
                         'v sootvetstvuyushchej pozicii 2-go massiva
560 NEXT N               'sleduyushchij bit
570 NEXT M               'sleduyushchij bajt

   Nizkij uroven'.

   YAzyk assemblera delaet bitovye preobrazovaniya namnogo bystree.
Vot procedura, kotoraya delaet  eti  preobrazovaniya uzhasno bystro,
poskol'ku ona derzhit vse v mikroprocessore (ona nemnogo velikova-
ta, no Vy mozhete ispol'zovat' vzamen  algoritm, pokazannyj v Bej-
sike).   Procedura rabotaet, hranya 8 rezul'tiruyushchih bajtov v  re-
gistrah CX, DX, BP i DI. Bajt  ekrannyh dannyh pomeshchaetsya v AL, a
zatem v AH peredvigayutsya posledovatel'no CL, CH, DL i DH.  Kazhdyj
raz iz AL v AH sdvigaetsya odin  bit  i kogda sdelany 4 sdviga, to
CX  i  DX obmenivayutsya s DX i BP, posle chego vse eto  povtoryaetsya
snova.  |tot  process  povtoryaetsya  dlya  kazhdogo iz 8-mi ekrannyh
bajtov  i kogda on zavershen, to preobrazovannoe izobrazhenie  hra-
nitsya v registrah mikroprocessora, prichem samyj levyj bajt dannyh
dlya  pechati  v CL.  Soderzhimoe registrov vyvoditsya na  printer  i
obnulyaetsya, posle chego process  povtoryaetsya  dlya sleduyushchih vos'mi
bajtov ekrana.  Snachala poluchite 8 bajtov iz videobufera i pomes-


tite ih v bufer s imenem BUFFER.   Pomestite 0 v AX, CX, DX, BP i
DI. Zatem:

   LEA  BX,BUFFER    ;ukazyvaem na bufer videodannyh
   MOV  SI,0         ;smeshchenie v etom bufere
GET_BYTE:  MOV  AL,[BX][SI]     ;berem bajt
DO_HALF:   XCNG AH,CL           ;poluchaem CL, CH, DL i DH
   SHL  AX,1         ;sdvigaya bit iz AL
   XCNG AH,CL        ;
   XCNG AH,CH        ;
   SHL  AX,1         ;

   XCNG AH,CH        ;
   XCNG AH,DL        ;
   SHL  AX,1         ;
   XCNG AH,DL        ;
   XCNG AH,DH        ;
   SHL  AX,1         ;
   XCNG AH,DH        ;
;---nachinaem vtoruyu polovinu peremeshcheniya bitov
   XCNG CX,BP        ;obmenivaem soderzhimoe CX i DX
   XCNG DX,DI        ;
   CMP  SI,7         ;esli vse bajty preobrazovany, to pechataem
   JE   PRINT_BYTES  ;
   INC  SI           ;inache perehodim k sleduyushchemu bajtu
   JMP  SHORT GET_BYTE    ;
;---pechataem bajty
PRINT_BYTES:   PUSH DX    ;sohroanyaem DX
   MOV  AH,5         ;funkciya vyvoda na printer
   MOV  DL,27        ;kod Esc
   INT  21H          ;posylaem ego
   MOV  DL,75        ;kod graficheskogo rezhima
   INT  21H          ;posylaem ego
   MOV  DL,6         ;budet poslano 6 bajtov
   INT  21H          ;
   MOV  DL,0         ;
   INT  21H          ;
   CALL PRINT_2_BYTES  ;posylaem soderzhimoe CX
   POP  CX           ;
   CALL PRINT_2_BYTES  ;posylaem soderzhimoe DX
   MOV  CX,BP        ;
   CALL PRINT_2_BYTES  ;posylaem soderzhimoe BP
   MOV  DX,DI        ;
   CALL PRINT_2_BYTES  ;posylaem soderzhimoe DI
    .
   (idem k sleduyushchej gruppe iz vos'mi bajtov)
    .
PRINT_2_BYTES:    PROC  NEAR
   MOV  AH,5         ;funkciya pechati
   MOV  DL,CL        ;snachala CL
   INT  21H          ;pechataem
   MOV  DL,CH        ;zatem CH
   INT  21H          ;pechataem
   RET
PRINT_2_BYTES     ENDP







   Pri  asinhronnoj  svyazi  mashina posylaet ili  prinimaet  bajty
informacii po odnomu bitu.  Vremennye intervaly mezhdu bajtami pri
etom  nesushchestvenny,  no  vremena mezhdu otdel'nymi  bitami  bajta
ochen' vazhny.  Signal na  linii  mozhet  byt'  vysokogo ili nizkogo
urovnya,  chto sootvetstvuet logicheskim nulyu i edinice, i  govoryat,
chto liniya otmechena  (marking),  kogda  uroven'  vysokij, i pustaya
(spacing), kogda uroven' nizkij.
   Liniya  podderzhivaetsya v otmechennom sostoyanii, kogda po nej net
peredachi dannyh. Pri nachale peredachi bajta dannyh signal padaet v
0,  otmechaya  startovyj  bit.  Zatem sleduyut vosem'  bitov  dannyh
(inogda men'she) v vide nabora vysokih i nizkih urovnej. Poslednij
bit dannyh mozhet soprovozhdat'sya bitom chetnosti, ispol'zuemym  dlya
obnaruzheniya oshibok, a zatem v posledovatel'nost' vklyuchayutsya 1 ili
bolee  stop-bitov,  kotorym sootvetstvuet vysokij  uroven'.   |ti
stop-bity nachinayut otmechennoe sostoyanie, kotoroe budet sohranyat'-
sya do teh por, poka ne nachnetsya peredacha sleduyushchego bajta dannyh;
chislo ispol'zuemyh stop-bitov sushchestvenno, poskol'ku oni ustanav-
livayut  minimal'noe vremya, kotoroe dolzhno projti pered  sleduyushchim
startovym bitom. Na ris. 7-1 pokazana eta posledovatel'nost'.
   Konechno, peredayushchaya  i  priemnaya  stancii  dolzhny ispol'zovat'
odin  i tot zhe protokol dlya etih cepochek bitov i oni dolzhny rabo-
tat' s odnoj i toj  zhe  skorost'yu  obmena  (izmeryaemoj  v bitah v
sekundu, nazyvaemyh takzhe bodami).  Pri obmene mogut legko vozni-
kat' oshibki, poetomu  kommunikacionnoe oborudovanie predostavlyaet
raznoobraznuyu  informaciyu o statuse kak samogo porta, tak i  pri-
soedinennogo k nemu modema.  Zadachej modema yavlyaetsya preobrazova-
nie  signala,  generiruemogo portom kommunikacii, v  akusticheskij
signal, kotoryj mozhet zatem  byt'  peredan po telefonnomu kanalu.
Bol'shinstvo modemov predostavlyayut takzhe dopolnitel'nye kommunika-
cionnye vozmozhnosti,  takie  kak  avtomaticheskij  vyzov  i otvet,
kotorye ne podderzhivayutsya samim portom kommunikacii.




   Posledovatel'naya  svyaz' nastol'ko slozhna, chto byli razrabotany
special'nye  mikroshemy,  vypolnyayushchie  rabotu  po  formirovaniyu i
sinhronizacii strok bitov, sostavlyayushchih posledovatel'nye  dannye.
Takie  mikroshemy  nazyvayut  universal'nym  asinhronnym  priemni-
kom-peredatchikom (universal asynchronous receiver transmitter ili
UART). IBM PC ispol'zuet UART 8250 firmy Intel.
   Operacionnaya sistema podderzhivaet 2 porta kommunikacii, poeto-
mu  v mashine imeyutsya 2 mikroshemy.  Ih bazovye adresa hranyatsya  v
yachejke 0040:0000 dlya COM1 i  0040:0002  dlya  COM2. (Bazovyj adres
eto  2-hbajtovyj adres porta, kotoryj yavlyaetsya mladshim iz  gruppy
adresov portov, dayushchih dostup k UART.) Na vseh mashinah krome PCjr
COM1  imeet  bazovyj adres 3F8H, a COM2 - 2F8H; PCjr  imeet  svoj
vnutrennij modem po  adresu  3F8H,  a  COM1 - po adresu 3F8H. Dlya
udobstva,  my v dal'nejshem budem vsegda numerovat' registry 3FxH,
no vse skazannoe v ravnoj stepeni primenimo i k registram 2FxH.
   Mikroshema 8250 imeet 10  programmiruemyh  odnobajtnyh regist-
rov, s pomoshch'yu kotoryh upravlyaetsya i kontroliruetsya port kommuni-


kacii. Bol'shinstvo iz nih  zanimayutsya  inicializaciej porta, pro-
cessom,  kotoryj mozhet byt' ochen' slozhnym.  Dostup k etim 10  re-
gistram osushchestvlyaetsya cherez  sem' adresov portov s nomerami 3F8H
-  3FEH  (ili 2F8H - 2FEH).  V pyati sluchayah  registr, k  kotoromu
poluchaem dostup cherez dannyj port,  zavisit ot togo, kak ustanov-
len bit 7 v registre kontrolya linii, kotoryj yavlyaetsya  edinstven-
nym registrom s adresom porta 3FBH. Vot eti registry:

3F8H (OUT, bit 7 = 0 v 3FBH)   Registr hraneniya peredatchika
3F8H (IN, bit 7 = 0 v 3FBH)    Registr dannyh priemnika
3F8H (OUT, bit 7 = 1 v 3FBH)   Delitel' skorosti obmena (mladshij)
3F9H (IN, bit 7 = 1 v 3FBH)    Delitel' skorosti obmena (starshij)
3F9H (OUT, bit 7 = 0 v 3FBH)   Registr razresheniya preryvaniya
3FAH (IN)                      Registr identifikacii preryvaniya
3FBH (OUT)                     Registr upravleniya linii
3FCH (OUT)                     Registr upravleniya modemom
3FDH (IN)                      Registr statusa linii
3FEH (IN)                      Registr statusa modema

   Iz desyati registrov tol'ko shest' neobhodimy dlya prostoj posle-
dovatel'noj svyazi.  Registr  hraneniya  peredatchika  soderzhit bajt
dannyh, kotorye budut poslany [7.1.6], a registr dannyh priemnika
- poslednij poluchennyj bajt dannyh [7.1.7]. Registry upravleniya i
statusa linii inicializiruyut i upravlyayut liniej svyazi,  ispol'zuya
skorost' obmena, soderzhashchuyusya v  dvuh registrah delitelya skorosti
obmena [7.1.2]. Iz ostavshihsya chetyreh registrov registry upravle-
niya i statusa  modema  ispol'zuyutsya  tol'ko dlya svyazi cherez modem
[7.1.5],  a  dva registra, svyazannyh s preryvaniyami  ispol'zuyutsya
tol'ko v procedurah, upravlyaemyh preryvaniyami [7.1.8].
   Preryvaniya ispol'zuyutsya pri svyazi v celyah effektivnosti. Obych-
naya kommunikacionnaya procedura nepreryvno proveryaet registr  sta-
tusa linii, ozhidaya vvodimogo simvola ili ukazaniiya, chto vse goto-
vo  dlya  peredachi sleduyushchego bajta dannyh.   Poskol'ku  processor
namnogo bystree, chem obychnye skorosti  s kotorymi peredayutsya pos-
ledovatel'nye dannye, to etot metod naprasno rashoduet processor-
noe vremya, kotoroe mozhet ispol'zovat'sya dlya obrabotki postupayushchih
ili  peredavaemyh dannyh.  Po etoj prichine mikroshema 8250  mozhet
byt' ustanovlena v  rezhim,  vyzyvayushchij  preryvanie  pri poyavlenii
simvola,  vozniknovenii oshibki i t.p.  |to preryvanie momental'no
vyzovet proceduru Vashej programmy, kotoraya, skazhem, budet pereda-
vat' sleduyushchij simvol iz kommunikacionnogo bufera.




   Pri  inicializacii porta kommunikacii ("otkrytii")  ustanavli-
vayutsya vse  ego  parametry.  |ti  parametry  dlinu  slova,  chislo
stop-bitov, ustanovku chetnosti i skorost' obmena. Dlina slova eto
chislo bitov, kotoroe obrazuet  osnovnuyu  edinicu dannyh.  Esli my
rabotaem  s privychnymi porciyami po 8 bitov, to 7 bitov dostatochny
dlya standartnyh fajlov ASCII (v  kotoryh  vse simvoly imeyut kody,
ne  prevyshayushchie ASCII 128), v to vremya kak dlya peredachi chislennyh
dannyh dostatochno porcij po 4 bita.


   Vysokij uroven'.

   Bejsik otkryvaet kommunikacionnyj  kanal kak fajl, i kak tako-
vomu emu dolzhen byt' prisvoen identifikacionnyj nomer:

   OPEN "COM1: .........." AS #1

V  kavychkah dolzhna byt' pomeshchena vsya informaciya, neobhodimaya  dlya
inicializacii porta  kommunikacii,  pri etom kazhdyj element otde-
lyaetsya  ot predydushchego zapyatoj.  Inicializacionnye dannye  vsegda
vvodyatsya v sleduyushchem poryadke:

Skorost' obmena   daetsya kak celoe chislo: 75, 100, 150, 300, 600,
                  1200, 1800, 2400, 4800 ili 9600 bod. Po umolcha-
                  niyu beretsya skorost' obmena 300 bod.
CHetnost'          vvoditsya kak odnosimvol'nyj kod: O dlya nechetnoj
                  E - dlya chetnoj i N - pri otsutstvii kontrolya po
                  chetnosti.  Mogut byt'  takzhe S - kogda bit chet-
                  nosti  vsegda raven 0 i M - kogda bit  chetnosti
                  vsegda raven 1. Esli ispol'zuyutsya 8 bit dannyh,
                  to  nado ukazyvat' N; pri ispol'zovanii chetyreh
                  bit ne nado ispol'zovat' N. Po umolchaniyu - E.
Bity dannyh       daetsya  kak  celoe  chislo  4, 5, 6, 7 ili 8. Po
                  umolchaniyu beretsya 7.
Stop-bity         daetsya  kak  celoe  chislo  1  ili 2, prichem 2 -
                  znachenie  po umolchaniyu dlya 75 i 110 bod, a 1  -
                  dlya ostal'nyh. Kogda chislo bitov dannyh ravno 4
                  ili  5, to 2 oboznachaet 1 1/2 stop-bita.  Takoe
                  znachenie vozmozhno pri  kommunikacii,  tak kak v
                  etom  sluchae  bit yavlyaetsya edinicej  vremeni  i
                  poetomu delim.

Operator OPEN "COM1:" AS #1 otkryvaet COM1 dlya svyazi so skorost'yu
300   bod  s  chetnoj  chetnost'yu,  ispol'zuya 7  bitov  dannyh i  1
stop-bit. OPEN "COM1:1200,O,8,1" ustanavlivaet skorost' 1200 bod,
nechetnuyu chetnost', 8 bit na simvol i 1 stop-bit.  Otmetim, chto Vy
mozhete zavershit' operator OPEN  vyrazheniem LEN = chislo, gde chislo
ustanavlivaet  maksimal'nyj razmer bloka, s kotorym operatory GET
i PUT mogut obrabatyvat' dannye (po umolchaniyu 128 bajtov). Imeet-
sya takzhe ryad komand upravleniya modemom, kotorye takzhe mogut  byt'
vklyucheny v etu specifikaciyu. (V  [7.1.5]  ob®yasnyaetsya special'naya
terminologiya, ispol'zuemaya pri etom):

   RS     Podavlyaet signal "Zapros na posylku" (Request to send).
          Esli eta komanda opushchena, to OPEN "COM" vklyuchaet RTS.

   CS     Vyzyvaet  proverku linii "Ochistka posylki"  (Clear  to
          send).  Za etoj komandoj mozhet sledovat' znachenie (ot 0
          do  65535), dayushchee chislo millisekund kotorye budet ozhi-
          dat'sya signal pered tem kak budet vydana oshibka tajmau-
          ta,  naprimer, CS500.  Znachenie po umolchaniyu 1000, esli
          ukazan parametr RS, v etom sluchae 0.
   DS     Vyzyvaet  proverku  linii  "Gotovnost'  nabora  dannyh"
          (Data set ready).  Dopuskaetsya neobyazatel'nyj parametr,
          kak i dlya CS. Znachenie po umolchaniyu 1000.


   CD     Vyzyvaet proverku linii "Opredelenie nositelya" (Carrier
          detect). Dopuskaetsya neobyazatel'nyj vremennoj parametr,
          kak i dlya CS. Znachenie po umolchaniyu 0.
   LF     Vyzyvaet  avtomaticheskuyu  podachu  koda perevoda stroki
          (ASCII 10) posle kazhdogo simvola vozvrata karetki  (AS-
          CII 13). Ispol'zuetsya dlya  posledovatel'nogo  vyvoda na
          printer.
   PE     Razreshaet proverku chetnosti, vyzyvaya  oshibku  tajmauta
          ustrojstva pri vozniknovenii oshibki chetnosti.

   |ti special'nye komandy mogut  pomeshchat'sya v lyubom meste opera-
tora  OPEN "COM" i v lyubom poryadke.  Otmetim, chto obychno  signaly
CTS i DSR dolzhny byt' ustanovleny,  chtoby operator OPEN vypolnil-
sya, a inache budet vydana oshibka tajmauta ustrojstva. V zaklyuchenie
privodim operator OPEN "COM", soderzhashchij  vse parametry, krome RS
i LF:

   OPEN "COM1:1200,O,7,1,CS2000,DS2000,CD,PE" AS #1 LEN = 256

   Srednij uroven'.

   Funkciya  0 preryvaniya 14H BIOS inicializiruet port  kommunika-
cii.  V DX dolzhen davat'sya nomer kommunikacionnogo kanala (COM1 =
0,  COM2  = 1).  V AL dolzhen soderzhat'sya  bajt  inicializacionnyh
dannyh, znachenie bitov kotorogo sleduyushchee:

   bity 1-0   dlina slova. 10 = 7 bitov, 11 = 8 bitov.
          2   chislo stop-bitov. 0 = 1, 1 = 2.
        4-3   chetnost'. 00 ili 10 = net, 01 = nechet., 11 = chet.
        7-5   skorost' obmena. 000 = 110 bod
                               001 = 150 bod
                               010 = 300 bod
                               011 = 600 bod
                               100 = 1200 bod
                               101 = 2400 bod
                               110 = 4800 bod
                               111 = 9600 bod

   V dannom primere port  inicializiruetsya  so  slovom v 8 bitov,
odnim stop-bitom i chetnoj chetnost'yu. Skorost' obmena 1200 bod.

;---prisvaivaem znacheniya parametrov peremennym
   MOV  WORDLENGTH,00000011B   ;dlina slova 8 bitov
   MOV  STOPBITS,00000000B     ;1 stop-bit
   MOV  PARITY,00011000B       ;chetnaya chetnost'
   MOV  BAUDRATE,10000000B     ;skorost' 1200 bod

;---inicializiruem COM1
   MOV  AL,0                   ;chistim AL
   OR   AL,WORDLENGTH          ;ustanavlivaem nuzhnye bity
   OR   AL,STOPBITS            ;
   OR   AL,PARITY              ;
   OR   AL,BAUDRATE            ;


   MOV  AH,0                   ;funkciya inicializacii porta
   MOV  DX,0                   ;vybiraem COM1
   INT  14H                    ;inicializiruem port

   Nizkij uroven'.

   Nezavisimo ot togo, zanimaemsya  li  my vvodom ili vyvodom, kak
minimum  4 registra mikroshemy 8250 dolzhny byt'  inicializirovany
dlya operacij obmena.  |to  registry delitelya skorosti obmena, re-
gistr kontrolya linii i registr razresheniya preryvaniya.

Inicializaciya skorosti obmena.

   Delitel'  skorosti obmena eto chislo, na kotoroe nado razdelit'
chastotu sistemnyh chasov  (1190000  gerc), chtoby poluchit' zhelaemuyu
skorost' obmena.  Naprimer, dlya skorosti obmena 1200 bod delitel'
skorosti obmena dolzhen byt' raven  96, poskol'ku 1190000/96 prib-
lizhenno  ravno  1200.  CHem bol'she delitel', tem  men'she  skorost'
obmena. Skorosti obmena 300 i  men'she  trebuyut dvuhbajtnogo chisla
dlya delitelya.  Starshij bajt posylaetsya v 3F9H (ili 2F9H), a mlad-
shij v 3F8H (2F8H).  V  oboih  sluchayah  bit  7 registra upravleniya
linii  dolzhen byt' ustanovlen v 1 pered zasylkoj znachenij; v pro-
tivnom sluchae po etim dvum  adresam  znacheniya  budut adresovany v
drugie registry (sm. [7.1.0]).  Vot nekotorye znacheniya, trebuemye
dlya obychnyh skorostej obmena:

   Skorost' obmena             3F9H            3F8H

        110                     04H             17H
        300                     01H             80H
        600                     00H             C0H
       1200                     00H             60H
       1800                     00H             40H
       2400                     00H             30H
       3600                     00H             20H
       4800                     00H             18H
       9600                     00H             0CH

   Vsegda  ustanavlivajte  registry skorosti obmena pervymi,  tak
kak oni edinstvennye, kotorye trebuyut, chtoby byl ustanovlen bit 7
v  registre kontrolya linii.  Posle etogo nado izmenit' soderzhimoe
registra kontrolya linii,  sbrasyvaya  7-j bit, chtoby vse ostal'nye
dostupy k registram byli pravil'nymi.  Poskol'ku registr kontrolya
linii yavlyaetsya registrom tol'ko  dlya  zapisi, to net sposoba ver-
nut' bit 7 obratno v 1 bez odnovremennoj ustanovki vseh ostal'nyh
bitov etogo registra. Otmetim, chto PCjr ispol'zuet drugie delite-
li, opisanie kotoryh Vy mozhete najti v tehnicheskom rukovodstve.

Inicializaciya registra kontrolya linii.

   Znachenie  bitov registra kontrolya linii, adres porta  kotorogo
raven 3FBH (ili 2FBH), sleduyushchee:

   bity 1-0   Dlina simvola. 00 = 5 bitov, 01 = 6 bitov
                             10 = 7 bitov, 11 = 8 bitov


          2   CHislo stop-bitov. 0 = 1, 1 = 1.5, esli dlina
                                pyati, inache 2.
          3   CHetnost'. 1 = generiruetsya bit chetnosti, 0 = net.
          4   Tip chetnosti. 0 = nechetnaya, 1 = chetnaya
          5   Fiksaciya chetnosti. Zastavlyaet bit chetnosti vsegda
              byt' 0 ili 1. 0 = otmenena
                  1 = vsegda 1, esli bit 3 = 1 & bit 4 = 0
              ili 1 = vsegda 0, esli bit 3 = 1 & bit 4 = 1
              ili 1 = net chetnosti, esli bit 3 = 0
          6   Ustanovka pereryva. Vyzyvaet vyvod stroki nulej
              v kachestve signala otdalennoj stancii.
              0 = zapreshcheno, 1 = pereryv
          7   Menyaet adresa portov drugih registrov

Obychno bity 5-7 sbrosheny v 0. Ostal'nye opisyvayut znacheniya, opre-
delyaemye protokolom obmena.

Registr razresheniya preryvaniya.

   Dazhe  esli  Vy ne ispol'zuete preryvaniya, vse ravno Vy  dolzhny
proizvesti zapis' v  registr  razresheniya  preryvaniya,  chtoby byt'
uverennym,  chto  preryvaniya zapreshcheny.  Prosto  pomestite v  etot
registr 0. Registr identifikacii preryvaniya mozhno ignorirovat'.
   Inicializaciya ostal'nyh  registrov  svyazana  s modemami. YAsno,
chto modemy nuzhny tol'ko dlya svyazi s udalennymi ustrojstvami, a ne
dlya upravleniya blizlezhashchimi  ustrojstvami,  takimi kak posledova-
tel'nyj printer. V [7.1.5] ob®yasneno kak inicializirovat' registr
kontrolya modema.
   V dannom primere iz oblasti  dannyh BIOS beretsya bazovyj adres
COM1, posle chego razlichnye registry inicializiruyutsya dlya skorosti
obmena 1200  bod,  semibitnyh  dannyh,  chetnoj  chetnosti i odnogo
stop-bita.

;---poluchaem bazovyj adres COM1
   MOV  AX,40H          ;ES ukazyvaet na oblast' dannyh BIOS
   MOV  ES,AX           ;
   MOV  DX,ES:[0]       ;poluchaem bazovyj adres COM1
;---inicializiruei registry delitelya skorosti obmena na 1200 bod
   ADD  DX,3            ;ukazyvaem na registr kontrolya linii
   MOV  AL,10000000B    ;ustanavlivaem bit 7
   OUT  DX,AL           ;posylaem bajt
   DEC  DX              ;ukazyvaem na starshij bajt delitelya
   DEC  DX              ;skorosti obmena
   MOV  AL,0            ;starshij bajt dlya 1200 bod
   OUT  DX,AL           ;posylaem starshij bajt dlya 1200 bod
   DEC  DX              ;ukazyvaem na mladshij bajt delitelya
   MOV  AL,60H          ;mladshij bajt delitelya dlya 1200 bod
   OUT  DX,AL           ;posylaem mladshij bajt
;---inicializiruem registr kontrolya linii
   MOV  AL,0            ;obnulyaem AL
   OR   AL,10B          ;dlina dannyh 7 bitov
   OR   AL,000B         ;1 stop-bit
   OR   AL,1000B        ;generiruetsya bit chetnosti
   OR   AL,10000B       ;chetnaya chetnost'


   ADD  DX,3            ;ukazyvaet na registr kontrolya linii
   OUT  DX,AL           ;posylaem inicializacionnoe znachenie

;---inicializiruem registr razresheniya preryvaniya
   DEC  DX              ;ukazyvaem na registr razresheniya
   DEC  DX              ;preryvaniya
   MOV  AL,0            ;zapreshchaem preryvaniya
   OUT  DX,AL           ;posylaem bajt




   Imeyutsya  dva  sposoba,  kotorymi  programma  mozhet opredelit',
kakoj iz kommunikacionnyh portov dolzhen ispol'zovat'sya.  Odin  iz
sposobov sostoit v ukazanii  nomera kanala v operatore programmy.
Vtoroj sposob sostoit v napisanii programmy dlya obmena cherez port
COM1, no izmenenii  kommunikacionnogo adaptera, dostup k kotoromu
idet cherez COM1.
   Oblast'  dannyh  BIOS  soderzhit mesto dlya  chetyreh  2-hbajtnyh
peremennyh, kotorye  soderzhat   bazovye  adresa  kommunikacionnyh
kanalov (MS DOS podderzhivaet tol'ko pervye dva iz nih).   Bazovyj
adres porta eto mladshij iz  gruppy  adresov portov, cherez kotorye
mozhno poluchit' dostup k dannomu kommunikacionnomu kanalu. Bazovyj
adres dlya COM1 hranitsya v yachejke 0040:0000, a dlya COM2 - v yachejke
0040:0002. Dlya smeny kommunikacionnyh portov nado prosto pomenyat'
eti dva znacheniya.  Povtornaya  smena  znachenij privedet k pervona-
chal'nomu naznacheniyu portov.

   Vysokij uroven'.

   V Bejsike operator OPEN "COM" mozhet ispol'zovat'sya v vide OPEN
C$+"1200,N,8" AS  #2,  gde  C$  mozhet  byt'  libo  "COM1:",  libo
"COM2:".  V kachestve al'ternativy mozhno ispol'zovat' PEEK i  POKE
dlya obmena bazovyh adresov:

100 DEF SEG = &H40          'ukazyvaem na oblast' dannyh BIOS
110 X = PEEK(0): Y = PEEK(1)  'zapominaem pervye 2 bajta
120 POKE 0,PEEK(2): POKE 1,PEEK(3)  'perenosim 2-e dva bajta
130 POKE 2,X: POKE 3,Y      'zasylaem zapomnennye znacheniya

   Srednij uroven'.

   Esli programma  obrashchaetsya  k  kommunikacionnomu  portu  cherez
preryvanie  14H  BIOS,  to COM port opredelyaetsya  soderzhimym  DX,
kotoroe ravno 0 ili 1  (dlya  COM1  ili  COM2). Vmesto togo, chtoby
prisvaivat' DX neposredstvennoe znachenie, zapolnyajte ego iz pere-
mennoj, kotoroj mozhet byt' prisvoeno znachenie 0 ili 1. Programmy,
ispol'zuyushchie kommunikacionnye funkcii 3 i 4 preryvaniya 21H vsegda
adresuyutsya k COM1. V etom sluchae nado pomenyat' bazovye adresa:

;---obmen bazovyh adresov dlya COM1 i COM2
   MOV  AX,40H        ;ES ukazyvaet na oblast' dannyh BIOS
   MOV  ES,AX         ;
   MOV  DX,ES:[0]     ;pomeshchaem 1-j bazovyj adres v DX


   MOV  AX,ES:[2]     ;pomeshchaem 2-j bazovyj adres v AX
   MOV  ES:[0],AX     ;obmenivaem adresa
   MOV  ES:[2],DX     ;




   Registr statusa linii mikroshemy UART 8250 opredelyaet protokol
svyazi.   |tot registr imeet adres porta na 5 bol'she, chem  bazovyj
adres dannogo kanala.  Obychno on postoyanno prosmatrivaetsya v pro-
cesse kommunikacionnogo obmena. Pri peredache dannyh registr soob-
shchaet, chto predydushchij simvol uzhe  poslan, pozvolyaya programme zapi-
sat' novyj simvol poverh ego.  Pri prieme dannyh registr informi-
ruet programmu o  postuplenii  sleduyushchego  simvola,  s  tem chtoby
programma mogla prochitat' ego prezhde chem on budet unichtozhen  sle-
duyushchim pribyvshim. Znachenie bitov etogo registra sleduyushchee:

   bit 0   1 = bajt dannyh poluchen
       1   1 = poluchennye dannye byli perezapisany (predydushchij
               simvol ne byl vovremya schitan)
       2   1 = oshibka chetnosti (veroyatno, iz-za shuma v linii)
       3   1 = oshibka okruzheniya (peredacha ne sinhronizovana)
       4   1 = obnaruzhen pereryv (poluchena dlinnaya stroka edinic,
               indiciruyushchaya, chto drugaya stanciya zaprashivaet
               konec peredachi)
       5   1 = registr hraneniya peredatchika pust (v etot registr
               dolzhny pomeshchat'sya peredavaemye dannye)
       6   1 = registr sdviga peredatchika pust (etot registr po-
               luchaet dannye iz registra hraneniya i preobrazuet
               ih v posledovatel'nyj vid)
       7   1 = tajmaut (ustrojstvo ne svyazano s mashinoj)

   Vysokij uroven'.

   V Bejsike snachala opredelite  bazovyj adres ispol'zuemogo kom-
munikacionnogo  porta, zatem dobav'te k nemu 5 i ispol'zujte ope-
rator INP dlya polucheniya  bajta  iz  etogo  porta.  V prilozhenii B
ob®yasnyaetsya kak v Bejsike proizvodyatsya bitovye operacii,  kotorye
neobhodimo prodelat' programme,  chtoby  interpretirovat' znachenie
etogo bajta.  V sleduyushchem primere proveryaetsya bit nalichiya perery-
va:

100 DEF SEG = &H40         'ukazyvaem na oblast' dannyh BIOS
110 ADDR = PEEK(4)+PEEK(5)*256   'vychislyaem adres COM2
120 X = INP(ADDR+5)        'vychislyaem adres registra statusa
130 IF X AND 16 THEN 500   'perehod na podpr-mu, esli bit 4 = 1
 .
 .
500 '''nachinaem proceduru obrabotki pereryva

   Srednij uroven'.

   Funkciya 3 preryvaniya 14H BIOS  vozvrashchaet v AH registr statusa
linii (AL poluchaet registr statusa modema [7.1.5]).  Pri vhode DX
dolzhen soderzhat' nomer  kommunikacionnogo  porta, k kotoromu osu-


shchestvlyaetsya  dostup, gde COM1 = 0, a COM2 = 1.  Kak i  predydushchij
primer, etot proveryaet nalichie pereryva:

   MOV  AH,3          ;nomer funkcii
   MOV  DX,1          ;vybiraem COM2
   INT  14H           ;poluchaem bajt statusa
   TEST AH,10000B     ;obnaruzhen pereryv?
   JNZ  BREAK_DETECT  ;esli da, to na proceduru obrabotki

   Nizkij uroven'.

   |tot primer sovershenno analogichen  privedennomu na Bejsike. Iz
oblasti  dannyh BIOS schityvaetsya bazovyj adres  kommunikacionnogo
kanala, k nemu dobavlyaetsya 5, a zatem iz poluchennogo adresa porta
schityvaetsya bajt statusa.

   MOV  AX,40H          ;ES ukazyvaet na oblast' dannyh BIOS
   MOV  ES,AX           ;
   MOV  DX,ES:[2]       ;poluchaem bazovyj adres COM2
   ADD  DX,5            ;dobavlyaem 5 dlya registra statusa
   IN   AL,DX           ;poluchaem bajt statusa
   TEST AL,10000B       ;bit 5 ustanovlen?
   JNZ  BREAK_DETECT    ;esli da, to na obrabotku pereryva




   Imeetsya  6 linij, po kotorym modemy svyazyvayutsya s  komp'yuterom
(usovershenstvovannye modeli  mogut  imet' dobavochnye linii po in-
terfejsu RS232). Vot ih nazvaniya, sokrashcheniya i funkcii:

Ot komp'yutera k modemu:

Data Terminal Ready (DTR)        Informiruet modem, chto komp'yuter
Gotovnost' komp'yutera            vklyuchen i gotov k svyazi.

Request To Send (RTS)            Informiruet modem, chto komp'yuter
Zapros na posylku                ozhidaet posylki dannyh.

Ot modema k komp'yuteru:

Data Set Ready (DSR)             Informiruet komp'yuter, chto modem
Gotovnost' modema                vklyuchen i gotov.

Clear To Send (CTS)              Informiruet komp'yuter, chto modem
Gotovnost' k posylke             gotov nachat' peredachu dannyh.

Data Carrier Detect (DCD)        Informiruet komp'yuter, chto modem
Obnaruzhen nositel' dannyh        svyazan s drugim modemom.

Ring Indicator (RI)              Informiruet komp'yuter, chto tele-
Indikator zvonka                 fonnaya liniya, po kotoroj prisoe-
                                 dinen modem imeet zvonok.

   Snachala komp'yuter  ustanavlivaet signal DTR, a zatem instukti-
ruet modem svyazat'sya s udalennoj stanciej.  Posle togo, kak modem


ustanovil svyaz' on ustanavlivaet signal DSR. |tot signal informi-
ruet komp'yuter, chto modem gotov k svyazi i v etot moment komp'yuter
mozhet ustanovit' signal RTS. Kogda modem otvetit signalom CTS, to
peredacha nachinaetsya.
   Dve standartnye linii, po kotorym komp'yuter upravlyaet modemom,
dostupny cherez registr kontrolya modema mikroshemy UART 8250. |tot
registr  imeet adres porta na 4 bol'she, chem bazovyj adres ispol'-
zuemogo kommunikacionnogo kanala. Vot znachenie ego bitov:

Registr kontrolya modema:

   bity 7-5     (vsegda 0)
          4     1 = vyhod UART zamknut na vhod
          3     dobavochnyj pol'zovatel' naznachen na vyvod #2
          2     dobavochnyj pol'zovatel' naznachen na vyvod #1
          1     1 = "zapros na posylku" aktiven
          0     1 = "gotovnost' komp'yutera" aktivna

   Obychno ustanovleny bity 0  i  1  registra  kontrolya  modema, a
ostal'nye  ravny 0.  Bit 2 raven 0, za isklyucheniem sluchaev, kogda
proizvoditel' modema prednaznachil  ego dlya special'nogo ispol'zo-
vaniya.  Bit 3 ustanovlen tol'ko v sluchae, kogda ispol'zuyutsya pre-
ryvaniya [7.1.8]. Nakonec, bit 4  predostavlyaet vozmozhnost' testi-
rovaniya  kommunikacionnyh programm bez ustanovleniya real'noj svya-
zi.  Vyhodnoj signal mikroshemy  UART podaetsya na vhod, kak budto
UART  prinimaet posledovatel'nye dannye.  |to svojstvo mozhno  is-
pol'zovat' dlya testirovaniya pravil'nosti raboty samoj mikroshemy.
Ono nedostupno pri ispol'zovanii kommunikacionnyh procedur prery-
vaniya 14H BIOS.
   CHetyre linii, po kotorym modem posylayut informaciyu komp'yuteru,
upravlyayutsya registrom statusa modema.  |tot registr raspolozhen po
adresu porta na 6 bol'she, chem  bazovyj adres ispol'zuemogo kommu-
nikacionnogo adaptera. Vot znachenie ego bitov:

Registr statusa modema:

   bit 7      1 = DCD
       6      1 = RI
       5      1 = DSR
       4      1 = CTS
       3      1 = izmenenie v DCD
       2      1 = izmenenie v RI
       1      1 = izmenenie v DSR
       0      1 = izmenenie v CTS

   Programma  nepreryvno proveryaet eti bity v hode kommunikacion-
nyh operacij.  Otmetim, chto  4  mladshih  bita parallel'ny starshim
chetyrem bitam.  |ti bity ustanavlivayutsya v 1 tol'ko togda,  kogda
proishodit izmenenie v statuse  sootvetstvuyushchego  starshego bita s
teh por, kogda registr chitalsya poslednij raz.  Vse 4 mladshih bita
avtomaticheski sbrasyvayutsya pri chtenii registra.  Programmy lyubogo
urovnya  mogut pryamo chitat' etot registr.  Drugoj vozmozhnost'yu yav-
lyaetsya ispol'zovanie funkcii 3 preryvaniya 14H BIOS, kotoraya vozv-
rashchaet  registr statusa modema v AL (pri etom v AH  budet  soder-


zhat'sya registr  statusa  linii).  Pri  vhode  DX dolzhen soderzhat'
nomer kommunikacionnogo kanala (0 ili 1).
   Bol'shinstvo  modemov  imeet  namnogo bol'she  vozmozhnostej,  po
sravneniyu s temi, chto otrazheny v dvuh svyazannyh s modemom regist-
rah.   Imeyutsya vozmozhnosti avtomaticheskoj svyazi i avtomaticheskogo
otveta,  kotorye kontroliruyutsya upravlyayushchej strokoj.  |ta  stroka
posylaetsya v modem, kak budto  peredayutsya  obychnye dannye.  Modem
vydelyaet etu stroku iz dannyh po special'nomu simvolu, ispol'zue-
momu tol'ko dlya ukazaniya nachala upravlyayushchej  stroki.  |tot simvol
mozhet  byt' predopredelennym (chasto ispol'zuetsya kod Esc -  ASCII
27) ili vybiraemym pol'zovatelem.  Modem sposoben opredelit' nas-
kol'ko  dlinnoj dolzhna byt' kazhdaya stroka, poetomu  po  okonchanii
stroki on opyat' rassmatrivaet  vhodyashchij potok informacii kak dan-
nye.   Kazhdyj modem imeet svoj nabor komand.  V kachestve  primera
rassmotrim komandy, ispol'zuemye vnutrennim modemom PCjr:

   Simvol          Znachenie          Primenenie

    A            otvet        vhod v rezhim otveta
    Bn           pereryv      posylaet signal pereryva n*100 ms
    Cn           otschet n     otschityvaet n zvonkov do otveta
    Dn...n       vyzov        posylaet stroku chisel n...n
    Fn           format       ustanavlivaet protokol svyazi
    H            razryv       prekrashchaet svyaz' s mashinoj
    I          inicializaciya  inicializiruet modem
    LR         dolgij otvet   menyaet ispol'zuemuyu kodovuyu sistemu
    M            rezhim        modem beret simvoly kak dannye
    Nn           novyj        menyaet komandnyj simvol na n
    O           originate     vhod v rezhim originate
    P            pick-up      vhod v rezhim golosa
    Q            zapros       zapros statusa modema

    R            povtor       povtorit' komandu svyazi
    Sn          skorost'      vybor skorosti obmena
    Tn...n     prozrachnost'   ignorirovat' upravlyayushchie stroki
                              v sleduyushchih n...n bajtah
    V            golos        perevesti modem v rezhim golosa
    W            ozhidanie     nichego ne delat' do sled. komandy
    X            peredat'     peredat' tona vyzova
    Z            test         provodit diagnostiku oborudovaniya

V otvet na  komandu  zaprosa  modem  posylaet  informaciyu o svoem
sostoyanii,  posylaya ee v UART kak obychnye dannye.  Pomimo  prochej
informacii, mozhet soobshchat'sya,  chto  liniya zanyata. CHtoby pravil'no
ispol'zovat' komandy upravleniya modemom i informaciyu o ego statu-
se nado tshchatel'no izuchit'  dokumentaciyu  na  dannyj modem.  Modem
PCjr  opisan v tehnicheskom rukovodstve po PCjr.   Nizheprivedennye
primery dayut tol'ko goluyu shemu ustanovleniya svyazi cherez modem.

   Vysokij uroven'.

   Poskol'ku telefonnaya svyaz' ochen' medlennaya, to svyaz' s modemom
eto odna iz oblastej, gde programmirovanie svyazi na Bejsike nichem
ne huzhe, chem na yazyke assemblera. Vot grubaya shema:


100 OUT BASEADDRESS+4,1        'ustanavlivaem bit DTR
110 '''teper' posylaem upravlyayushchuyu stroku dlya vyzova i ustanovle-
120 '''niya svyazi - etot kod menyaetsya ot modema k modemu
 .
 .
200 X = INP(BASEADDRESS+2)     'poluchaem registr statusa modema
210 IF X AND 2 <> 2 THEN 200   'zhdem poka budet ustanovlen bit 1
220 OUT BASEADDRESS+4,3        'ustanavlivaem bit RTS
230 X = INP(BASEADDRESS+2)     'poluchaem registr statusa modema
240 IF X AND 1 <> 1 THEN 230   'zhdem poka budet ustanovlen bit 0
250 '''teper' posylaem dannye

   Nizkij uroven'.

   Vot ta zhe samaya shema na yazyke assemblera:

;---ustanavlivaem signal DTR
   MOV  DX,BASE_ADDRESS    ;nachinaem s bazovogo adresa
   ADD  DX,4               ;ukazyvaem na registr kontrolya modema
   MOV  AL,1               ;ustanavlivaem bit 1
   OUT  DX,AL              ;posylaem v port
;---posylaem upravlyayushchuyu stroku modemu dlya vyzova
    .
   (etot kod raznyj dlya raznyh modemov)
    .
;---ozhidaem poka budet ustanovlen signal DSR
   INC  DX                 ;ukazyvaem na registr statusa modema
   INC  DX                 ;
TRY_AGAIN:  IN   AL,DX     ;poluchaem soderzhimoe
   TEST AL,10B             ;proveryaem vtoroj bit
   JZ   TRY_AGAIN          ;zhdem poka on ne budet raven 1

;---ustanavlivaem bit RTS
   DEC  DX                 ;vozvrashchaemsya k registru upravleniya
   DEC  DX                 ;
   MOV  AL,3               ;ustanavlivaem signal RTS
   OUT  DX,AL              ;posylaem v port
;---ozhidaem signala CTS
   INC  DX                 ;vozvrashchaemsya k registru statusa
   INC  DX                 ;
ONCE_MORE:  IN   AL,DX     ;poluchaem bajt statusa
   TEST AL,1               ;proveryaem bit CTS
   JZ   ONCE_MORE          ;ne prodolzhaem poka on ne ustanovlen
;---teper' mozhno posylat' dannye




   Peredacha  dannyh  proshche chem priem, poskol'ku  programma  imeet
polnyj kontrol' nad  sostavom  dannyh  i skorost'yu, s kotoroj oni
dolzhny  posylat'sya.  Tem ne menee procedury peredachi  mogut  byt'
dostatochno slozhnymi, esli oni  obrabatyvayut  dannye po mere togo,
kak  oni posylayutsya.  Mogut byt' takzhe problemy s  sinhronizaciej
pri ispol'zovanii protokola  XON/XOFF.   |tot protokol ispol'zuet
kody  ASCII  17(XON) i 19(XOFF), dlya togo  chtoby  signalizirovat'


prinimayushchej stancii,  chto  peredatchik  hochet  prodolzhit' peredachu
vremenno  prervannogo potoka dannyh.  CHtoby prinyat' eti  signaly,
programma dolzhna nepreryvno analizirovat' prinimaemye simvoly pri
peredache  (v  polnodupleksnom rezhime, v kotorom  obychno  rabotayut
modemy, signaly  odnovremenno  idut  v obe storony po telefonnomu
kanalu).   Krome  togo, chtoby obnaruzhit', chto  udalennaya  stanciya
posylaet stroku nulej, v kachestve signala pereryva, dolzhen nepre-
ryvno  analizirovat'sya  status bita pereryva (nomer  4)  registra
statusa linii [7.1.4]. Na ris.  7-2 (v [7.1.7]) pokazano kak pro-
cedura  peredachi dannyh vzaimodejstvuet s kodom, prinimayushchim dan-
nye.
   Vsledstvie etih prichin, predstavlennye v etom punkte procedury
otdel'no  peredayushchie dannye yavlyayutsya iskustvennymi.  No ih  mozhno
skombinirovat' s procedurami  priema dannyh, opisannymi v [7.1.7]
dlya sozdaniya obshchego predstavleniya o tom, chto nuzhno. YAsno, chto dlya
sozdaniya rabotosposobnoj  procedury  neobhodimo zatratit' bol'shie
usiliya,  osobenno  v chasti obnaruzheniya i ispravleniya  oshibok  pri
peredache dannyh.

   Vysokij uroven'.

   V Bejsike dlya togo, chtoby poslat' dannye v otkrytyj kommunika-
cionnyj port nado ispol'zovat' operatory PRINT#, PRINT# USING ili
WRITE#.  Poslednie dva operatora imeyut special'nyj format, paral-
lel'nyj  tomu,  kotoryj ispol'zuetsya imi pri vyvode  na  displej.
Obychno ispol'zuetsya operator PRINT#.  V dannom primere posylaemye
dannye berutsya neposredstvenno s klaviatury.  Predpolagaetsya, chto
COM1 uzhe otkryt, kak pokazano v [7.1.2].   Procedura obrabatyvaet
bit pereryva v registre statusa linii.

 .
 .
500 C$ = INKEY$: IF C$ <> "" THEN PRINT #1,C$
510 X = INP(BASEADDRESS + 5)    'chitaem registr statusa linii
520 IF X AND 32 = 32 THEN 1000  'proveryaem bit pereryva
530 IF EOF(1) THEN 500       'esli bufer pust, to zhdem vvoda
 .
 (zdes' raspolozhena procedura priema dannyh)
 .
1000 '''zdes' procedura obrabotki pereryva

   Srednij uroven'.

   Funkciya 1 preryvaniya 14H BIOS posylaet simvol, soderzhashchijsya  v
AL v kommunikacionnyj kanal. Pri vhode DX soderzhit nomer porta (0
ili 1).  Pri vozvrate AH soderzhit bajt statusa, v kotorom bit 7 =
1, esli operaciya neuspeshna.  V etom sluchae imeyut znachenie sleduyu-
shchie bity:

bit 4   obnaruzhen pereryv (signal "stop" ot prinimayushchej stancii)
    5   registr sdviga peredatchika pust
    6   registr hraneniya peredatchika pust

   MS DOS imeet funkciyu dlya  peredachi po kommunikacionnomu kanalu


simvola, pomeshchaemogo v DL. |to funkciya nomer 4 preryvaniya 21H, no
ona ne  imeet  nikakih  preimushchestv  pered  funkciej BIOS; ona ne
vozvrashchaet statusnoj informacii i ne pozvolyaet naznachat' kakoj iz
kommunikacionnyh portov  nado  ispol'zovat'  (vsegda ispol'zuetsya
COM1).
   CHtoby vyvesti stroku dannyz ispol'zujte funkciyu 40H preryvaniya
21H. |to obychnaya funkciya vyvoda  dlya  vseh fajlov i ustrojstv pri
ispol'zovanii metoda dostupa deskriptora fajlov.  COM1 imeet pre-
lopredelennyj nomer #3. Pomestite nomer fajla v BX, a chislo pere-
davaemyh  bajtov v CX.  Pust' DS:DX ukazyvayut na bufer  vyvodimyh
dannyh i vyzyvajte funkciyu.

   MOV  AH,40H         ;nomer funkcii
   MOV  BX,3           ;predopredelennyj nomer fajla dlya COM1
   MOV  CX,50          ;vyvodim 50 bajtov
   LEA  DX,DATA_BUFFER ;DS:DX ukazyvayut na bufer dannyh
   INT  21H            ;posylaem dannye
   JC   COM_ERROR      ;uhod na obrabotku oshibki

Otmetim, chto pri ispol'zovanii predopredelennyh nomerov fajlov ih
ne nado otkryvat'. Esli proizoshla oshibka, to ustanavlivaetsya flag
perenosa, a v AX  vozvrashchaetsya  5  esli  kommunikacionnyj port ne
gotov i 6 pri ukazanii nevernogo nomera fajla.

   Nizkij uroven'.

   Kogda  bajt dannyh pomeshchaetsya v registr hraneniya  peredatchika,
to on  avtomaticheski  vyvoditsya  v  posledovatel'nyj  kanal cherez
registr sdviga peredatchika, kotoryj serializuet dannye. Net neob-
hodimosti v impul'se bita  stroba,  kak eto delaetsya v sluchae pa-
rallel'nogo  adaptera.   Bit 5 registra statusa linii  pokazyvaet
svoboden li registr hraneniya  peredatchika  dlya priema dannyh. Re-
gistr  postoyanno  proveryaetsya  do teh por, poka bit 5  ne  stanet
ravnym 1.  Posle etogo v registr  hraneniya peredatchika posylaetsya
ocherednoj  bajt  iz togo mesta, otkuda oni berutsya.   V  processe
peredachi bit 5 raven 0 i tol'ko  kogda  on opyat' stanet ravnym 1,
to  v  registr hraneniya peredatchika mozhet byt'  poslan  sleduyushchij
simvol. |tot process povtoryaetsya do teh por, poka eto nuzhno.
   V sleduyushchem primere dany  osnovnye  ponyatiya ob etoj procedure.
Konechno, ona mozhet byt' sdelana neobychajno slozhnoj (v  chastnosti,
programmirovanie svyazi trebuet  osobo tshchatel'nyh procedur obnaru-
zheniya oshibok i vosstanovleniya pri sboyah). V primere predpolagaet-
sya, chto kommunikacionnyj port i  modem  uzhe inicializirovany, kak
pokazano  v  [7.1.2] i [7.1.5].  Pervaya chast' eto  cikl  proverki
oshibok i priema simvolov.  V  [7.1.7]  priveden kod dlya procedury
priema dannyh.

;---zhdem poka vse budet gotovo dlya posylki simvola
KEEP_TRYING:  MOV  DX,BASE_ADDRESS   ;bazovyj adres
   ADD  DX,5              ;ukazyvaem na registr statusa linii
   IN   AL,DX             ;poluchaem bajt statusa
   TEST AL,00011110B      ;proveryaem na oshibku
   JNZ  ERROR_ROUTINE     ;esli est', to na proceduru obrabotki
   TEST AL,00000001B      ;proveryaem polucheny li dannye


   JNZ  RECEIVE           ;esli da, to na proceduru priema
   TEST AL,00100000B      ;proveryaem gotovnost' k peredache
   JZ   KEEP_TRYING       ;esli net, to vozvrashchaemsya nazad
;---peredaem simvol prinimaemyj s klaviatury
   MOV  AH,1              ;funkciya proverki nazhatiya klavishi
   INT  16H               ;preryvanie klaviatury BIOS
   JZ   KEEP_TRYING       ;vozvrat, esli ne bylo nazhatiya
   MOV  AH,0              ;funkciya polucheniya koda s klaviatury
   INT  16H               ;teper' nuzhnyj simvol v AL
   SUB  DX,5              ;adres registra hraneniya peredatchika
   OUT  DX,AL             ;posylaem simvol
   JMP  SHORT KEEP_TRYING ;vozvrashchaemsya k nachalu cikla




   Kommunikacionnaya  programma gotova prinimat' dannye kak tol'ko
inicializirovan kommunikacionnyj port [7.1.2] i ustanovlena svyaz'
s  udalennoj stanciej [7.1.5].  Priem dannyh nikogda polnost'yu ne
otdelen ot peredachi dannyh,  poskol'ku  programme  mozhet potrebo-
vat'sya  poslat'  signal XOFF (ASCII 19), chtoby  ostanovit'  potok
dannyh, esli oni postupayut  slishkom  bystro  i ona ne uspevaet ih
obrabatyvat'.  Kod XON (ASCII 17) soobshchaet udalennoj stancii, chto
mozhno prodolzhit' peredachu.  Otmetim,  chto PCjr ne mozhet prinimat'
dannye  vo vremya diskovyh operacij; chtoby snyat'  eto  ogranichenie
mozhno ispol'zovat' XON i XOFF.
   V zavisimosti ot  slozhnosti  ispol'zuemogo  protokola  obmena,
prinimaemye dannye mogut trebovat' prostoj ili slozhnoj obrabotki.
Mozhet byt' poluchen odin iz nabora  upravlyayushchih kodov, privedennyh
v [7.1.9]. Te iz nih, kotorye yavlyayutsya ogranichitelyami dannyh chashche
obnaruzhivayutsya pri sinhronnom obmene.  Pri vyvode poluchaemyh sim-
volov na ekran uchityvajte vliyanie simvolov perevoda stroki (ASCII
10), poskol'ku nekotorye  yazyki  (vklyuchaya  Bejsik)  avtomaticheski
vstavlyayut  perevod  stroki posle vozvrata karetki; v etom  sluchae
isklyuchajte perevody stroki iz prinimaemyh  dannyh, chtoby izbezhat'
pustyh strok pri vyvode.  Na ris.  7-2 pokazana  kommunikacionnaya
procedura, vklyuchayushchaya takzhe kod peredachi, obsuzhdaemyj v [7.1.6].

   Vysokij uroven'.

   Dlya kommunikacionnoj procedury, napisannoj na interpretiruemom
Bejsike,  vremya ochen' sushchestvenno.  Obrabotka  medlenna,  poetomu
esli procedura priema neverno  skonstruirovana,  to vhodnoj bufer
mozhet  zapolnit'sya (t.e.  proizojdet perepolnenie) v to vremya kak
programma eshche budet  analizirovat'  ranee poluchennye dannye. Oche-
vidnym  resheniem  etoj  problemy yavlyaetsya  maksimal'no  vozmozhnyj
razmer bufera.  Pri zagruzke Bejsika razmer bufera vvoda ustanav-
livaetsya dobavleniem k komande klyucha /C:.  BASICA /C:1024 sozdaet
bufer razmerom v 1K i eto  minimal'noe  chislo dlya skorosti obmena
1200  bod (slozhnym proceduram mozhet ponadobit'sya 4096 bajt).   Po
umolchaniyu ispol'zuetsya razmer  bufera  ravnyj  256 bajtam i takoj
bufer imeet to preimushchestvo, chto on mozhet byt' celikom pomeshchen  v
odnu simvol'nuyu peremennuyu.  Takoj  razmer bufera mozhno ispol'zo-
vat' tol'ko pri skorosti obmena 300 bod i nizhe.
   Bejsik  chitaet  iz bufera s pomoshch'yu  operatora  INPUT$  (mozhno


ispol'zovat' takzhe INPUT# i LINE  INPUT#, no INPUT$ bolee gibok).
|tot operator imeet formu INPUT$(chislobajt,nomerfajla). Naprimer,
INPUT$(10,#1) chitaet 10 bajtov  iz kommunikacionnogo kanala, otk-
rytogo kak fajl #1.  Esli razmer bufera ne prevyshaet 256  bajtov,
to ochen' udobno chitat' vse  soderzhimoe  bufera  za odin raz.  LOC
soobshchaet  skol'ko bajtov dannyh nahoditsya v bufere v  dannyj  mo-
ment. Poetomu napishite  operator  INPUT$(LOC(1),#1)  i v S$ budut
zapisany vse dannye s momenta poslednego dostupa k buferu. Konech-
no, esli LOC(1) = 0, to  bufer  pust  i  procedura dolzhna ozhidat'
poka  dannye budut polucheny.  Otmetim, chto EOF(1) takzhe mozhno is-
pol'zovat' dlya  proverki  sostoyaniya  bufera,  tak kak eta funkciya
vozvrashchaet  -1  esli bufer pust i 0, esli tam est' hotya  by  odin
simvol.
   Posle togo kak dannye zapisany v S$ programma dolzhna proverit'
ne  soderzhatsya li tam upravlyayushchie kody.  Funkciya INSTR  vypolnyaet
etu zadachu bystree vsego.   Napomnim, chto ee parametrami yavlyayutsya
snachala  poziciya, s kotoroj nado vesti poisk v stroke, zatem  imya
stroki i, nakonec, simvol  (ili  stroka)  kotoryj  ishchetsya.  CHtoby
najti   simvol   XOFF  (ASCII  19)  operator  dolzhen  imet'   vid
INSTR(1,S$,CHR$(19)). CHtoby najti vtoroe poyavlenie nuzhnogo uprav-
lyayushchego  simvola  povtorite poisk v  stroke,  nachinaya s  simvola,
sleduyushchego za poziciej, v kotoroj najden pervyj.
   Obychno procedura vvoda  isklyuchaet bol'shinstvo upravlyayushchih sim-
volov  iz prinimaemyh dannyh, s tem chtoby oni normal'no vyglyadeli
pri vyvode.  Zatem dannye vyvodyatsya na ekran, peresylayutsya v dru-
goe  mesto v pamyati, a inogda zapisyvayutsya na disk ili  vyvodyatsya
na printer. V processe  vsej  etoj  deyatel'nosti programma dolzhna
postoyanno  vozvrashchat'sya k prosmotru ne postupili li novye dannye.
Esli okazalos', chto bufer zapolnyaetsya slishkom bystro, to program-
ma  mozhet poslat' signal XOFF, ostanavlivaya potok dannyh.  Zatem,
posle togo kak poluchennye  dannye  budu dekodirovany, mozhno snova
razreshit'  peredachu dannyh.  Konechno, neobhodimo  chtoby  protokol
obmena podderzhival XON i XOFF. Programmy, napisannye na interpre-
tiruemom Bejsike, obychno mogut ispol'zovat' XON/XOFF dlya ustanov-
leniya sootvetstviya skorostej  pri  prieme dannyh, no pri peredache
dannyh takaya programma chasto ne mozhet dostatochno bystro  otreagi-
rovat' na poluchenie signala XOFF.

 .
 .
500 '''zdes' nahoditsya procedura peredachi (sm. [7.1.6])
 .
 .
600 IF LOC(1)>100 THEN XOFF = 1: PRINT #1,CHR$(19)
610 C$ = INPUT$(LOC(1),#1)   'chitaem soderzhimoe bufera
620 '''vydelyaem iz dannyh upravlyayushchie simvoly
630 IF INSTR(1,C$,CHR$(19))>0 THEN 800  'poluchen XOFF
640 IF INSTR(1,C$,CHR$(17))>0 THEN 900  'poluchen XON
 .
 (zdes' udalyayutsya nenuzhnye upravlyayushchie simvoly
 .
700 PRINT C$                 'vyvodim dannye na ekran
710 IF LOC(1) > 0 THEN 600   'esli polucheny dannye, to chitaem ih


720 IF XOFF = 1 THEN XOFF = 0: PRINT #1,CHR$(17)
 .
 .
800 'reakciya na XOFF
 .
900 'reakciya na XON

   Esli funkciya LOF primenyaetsya k kommunikacionnomu portu, to ona
vozvrashchaet  kolichestvo svobodnogo mesta, ostavsheesya v bufere vvo-
da.  Naprimer, esli COM1 otkryt kak #1, to LOF(1) soobshchit svobod-
nogo  prostranstva.  |to mozhet byt' polezno dlya opredeleniya,  chto
bufer pochti polon.  Otmetim,  odnako, chto operator LOC vozvrashchaet
poziciyu ukazatelya v bufere i eto znachenie mozhet byt' ispol'zovano
dlya toj zhe  celi.  Naprimer,  esli  COM1  otkryt kak #3, a razmer
bufera  vvoda  raven  256 bajtam, to do teh por, poka  LOC(3)  ne
budet raven 256, bufer ne polon.

   Srednij uroven'.

   Funkciya 2 preryvaniya 14H BIOS ozhidaet simvol iz posledovatel'-
nogo porta, pomeshchaet ego v AL pri poluchenii i zatem  vozvrashchaetsya
v programmu. Pri vhode nado pomestit' nomer porta (0-1) v DX. Pri
vozvrate AX raven nulyu, esli ne bylo oshibki.  Esli AH ne raven 0,
to mozhet byt' vozvrashchen bajt  statusa,  v  kotorom imeyut znachenie
tol'ko 5 bitov. |to sleduyushchie bity:

bit  1   oshibka perepolneniya (novyj simvol postupil  ran'she,  chem
         byl udalen staryj)
     2   oshibka chetnosti (veroyatno, iz-za problem v linii)
     3   oshibka oformleniya (startovyj ili stop-bity neverny)
     4   obnaruzhen pereryv (poluchena dlinnaya stroka bitov 0)
     5   oshibka tajmauta (ne poluchen signal DSR)

   MS DOS takzhe predostavlyaet kommunikacionnuyu funkciyu dlya priema
odnogo simvola, eto funkciya  3  preryvaniya  21H.  Funkciya ozhidaet
simvol  iz COM1 i pomeshchaet ego v AL.  Otmetim, chto pri  etom  net
funkcii inicializacii porta,  kotoruyu nado delat' cherez proceduru
BIOS  ili neposredstvenno, kak pokazano v [7.1.2].  Po  umolchaniyu
port inicializiruetsya so  znacheniyami  2400 bod, net kontrolya chet-
nosti,  odin stop-bit i 8 bitov na simvol.  |ta funkciya ne  imeet
nikakih dostoinstv po sravneniyu  s  funkciej BIOS i ne vozvrashchaet
informacii o statuse.

   Nizkij uroven'.

   Pri  poluchenii dannyh bez ispol'zovaniya kommunikacionnogo pre-
ryvaniya [7.1.8]  programma  dolzhna  postoyanno  proveryat'  registr
statusa  linii, adres porta kotorogo na 5 bol'she bazovogo  adresa
ispol'zuemogo kommunikacionnogo  adaptera.  Bit  0 etogo registra
budet  raven nulyu, do teh por poka ne budet poluchen simvol v  re-
gistr dannyh priemnika.  Kogda bit 0 stanovitsya ravnym 1, to nado
nemedlenno  schitat' ego iz registra, s tem chtoby na nego ne nalo-
zhilsya sleduyushchij prinimaemyj simvol. Posle togo kak simvol schitan,
bit 0 opyat' stanovitsya ravnym 0 i ostaetsya takovym, poka ne  pri-


budet novyj simvol.
   Hotya zdes' ob etom ne govorilos', no kommunikacionnye procedu-
ry  obychno sozdayut ciklicheskij bufer dlya sbora postupayushchih simvo-
lov.  Ciklicheskie bufera obsuzhdalis'  v [3.1.1].  Vy dolzhny takzhe
znat', chto esli postupayushchie dannye podavat' na ekran so skorost'yu
1200 bod, to procedura sdviga ekrana  BIOS [4.5.1] ne budet uspe-
vat'  i  proizojdet perepolnenie.  Prostoe reshenie  etih  problem
sostoit v ispol'zovanii  kommunikacionnogo preryvaniya, kak ob®yas-
neno v [7.1.8].
   Sleduyushchij  primer  chastichno dubliruet  soderzhimoe  predydushchego
razdela, otnosyashchegosya k peredache simvolov. Kak i v tom sluchae kod
nachinaetsya  s beskonechnogo cikla.  Ob®edinite eti 2  procedury  s
procedurami inicializacii iz  [7.1.2]  i [7.1.5] dlya sozdaniya za-
konchennoj procedury vvoda/vyvoda cherez kommunikacionnyj kanal.

KEEP_TRYING:   MOV  DX,BASE_ADDRESS   ;bazovyj adres
   ADD  DX,5           ;ukazyvaem na registr statusa linii
   IN   AL,DX          ;poluchaem bajt statusa
   TEST AL,00011110B   ;proveryaem na oshibku
   JNZ  ERROR_ROUTINE  ;esli da, to na obrabotku oshibki

   TEST AL,00000001B   ;proveryaem polucheny li dannye
   JNZ  RECEIVE        ;na proceduru priema dannyh
   TEST AL,00100000B   ;proveryaem gotovnost' k peredache
   JZ   KEEP_TRYING    ;esli net, to k nachalu cikla
    .
   (zdes' raspolozhena procedura peredachi - sm. [7.1.6])
    .
;---poluchaem dannye i vyvodim ih na ekran
RECEIVE:   MOV  DX,BASE_ADDRESS        ;bazovyj adres
   IN   AL,DX          ;chitaem poluchennyj simvol
   CMP  AL,19          ;proverka na XOFF
   JE   XOFF_ROUTINE   ;
    .
   (i t.d.)
    .
   MOV  DL,AL          ;gotovim simvol dlya vyvoda na ekran
   MOV  AH,2           ;funkciya vyvoda simvola
   INT  21H            ;vyvodim ego
   JMP  SHORT KEEP_TRYING   ;vozvrashchaemsya na nachalo cikla




   Horoshaya kommunikacionnaya programma imeet slishkom mnogo raboty,
chtoby posvyatit' sebya celikom  vvodu/vyvodu.   Postupayushchie  dannye
dolzhny analizirovat'sya, peredavaemye dannye dolzhny sobirat'sya,  a
bol'shie bloki dannyh mogut zapisyvat'sya na disk ili schityvat'sya s
nego.  Kommunikacionnoe preryvanie pozvolyaet programme ne tratit'
na vvod/vyvod bol'she  vremeni,  chem  on  togo  trebuet. Naprimer,
posle ustanovki preryvaniya, upravlenie peredaetsya procedure pere-
dachi dannyz tol'ko v tom sluchae, kogda  registr hraneniya peredat-
chika  pust i vozvrashchaetsya programme, kak tol'ko poslan bajt  dan-
nyh, pozvolyaya ej prodolzhat' svoyu rabotu  do teh por, poka registr


hraneniya  peredatchika ne budet snova gotov.  Ne zabud'te  oznako-
mit'sya s obsuzhdeniem preryvanij  v [1.2.3], prezhde chem prodolzhit'
chtenie.
   IBM  PC otvodit dva apparatnyh preryvaniya dlya kommunikacionnyh
kanalov, nomer 3 (COM1) i 4 (COM2). Otmetim, chto u PCjr, vstroen-
nyj  modem imeet nomer 3, a COM1 - nomer 4.  Mikroshema UART 8250
dopuskaet 4 klassa preryvanij dlya  kazhdogo kanala, ispol'zuya sle-
duyushchie dvoichnye kodovye chisla:

   00     izmenenie v registre statusa modema
   01     registr hraneniya peredatchika pust
   10     polucheny dannye
   11     oshibka priema, ili polucheno uslovie pereryva

|ti  kody soderzhatsya v bitah 2-1 registra identifikacii  preryva-
niya, adres porta kotorogo na 2 bol'she,  chem bazovyj adres ispol'-
zuemogo kommunikacionnogo adaptera. Bit 0 etogo registra ustanav-
livaetsya pri vozniknovenii  preryvaniya,  a  ostal'nye bity ne is-
pol'zuyutsya i vsegda ravny 0.
   CHtoby  vybrat' odno ili bolee preryvanij, nado  zaprogrammiro-
vat' registr razresheniya  preryvaniya,  adres  kotorogo na 1 bol'she
bazovogo adresa. Znachenie ego bitov takoe:

bit 0     1 = preryvanie pri poluchenii dannyh
    1     1 = preryvanie kogda registr hraneniya peredatchika pust
    2     1 = preryvanie pri oshibke priema dannyh
    3     1 = preryvanie pri izmenenii registra statusa modema
  7-4     ne ispol'zuyutsya, vsegda 0

Kogda odno iz etih sobytij proishodit, to iniciiruetsya apparatnoe
preryvanie, voznikayushchee v mikrosheme obrabotki preryvanij 8259 po
kanalu  3  dlya COM1 i po kanalu 4 dlya COM2.  Procedura  obrabotki
preryvanij peredaet upravlenie  tomu  kodu,  na kotoryj ukazyvaet
sootvetstvuyushchij vektor preryvaniya.  Poskol'ku eto apparatnoe pre-
ryvanie, to ono mozhet  byt'  maskirovano  [1.2.2].   Pomnite, chto
procedura  obrabotki  preryvaniya dolzhna  zavershat'sya  standartnym
kodom vyhoda iz apparatnogo preryvaniya MOV AL,20H/OUT 20H,AL.  Na
ris. 7-3 pokazano kommunikacionnoe preryvanie.
   Lyuboe chislo tipov preryvaniya mozhet byt' razresheno  odnovremen-
no. No esli razreshen bolee chem  odin  tip, to procedura obrabotki
preryvaniya dolzhna sama opredelyat' kakoj iz tipov preryvaniya proi-
zoshel, proveryaya registr  identifikacii  preryvaniya.  Odnovremenno
mogut  proishodit' bolee chem odno preryvanie, poetomu  bit 0  re-

gistra identifikacii soobshchaet o  tom, chto postupilo eshche odno pre-
ryvanie. Kogda dva ili bolee preryvanij postupilo v odin i tot zhe
moment vremeni,  to  oni  obrabatyvayutsya  v  poryadke, ukazannom v
nizheprivedennoj tablice.  Dobavochnye preryvaniya dolzhny byt' obra-
botany  do  zaversheniya procedury obrabotki  preryvaniya.   Usloviya
predshestvuyushchih preryvanij "otmenyayutsya"   s pomoshch'yu dejstvij, pri-
vedennyh v pravom stolbce sleduyushchej tablicy:


Kod             Tip               Dejstviya dlya "sbrosa"

 11       oshibka ili pereryv     chtenie registra statusa linii
 10       polucheny dannye        chtenie registra priemnika dannyh
 01       peredatchik gotov       vyvod simvola v registr hraneniya
                                 peredatchika
 00    izmenenie statusa modema  chtenie registra statusa modema

   Nizkij uroven'.

   Vot  obshchaya  forma programmy,  obrabatyvayushchej  kommunikacionnye
preryvaniya:

;---ustanovka vektora kommunikacionnogo preryvaniya
   PUSH DS                  ;sohranyaem DS
   MOV  DX,OFFSET IO_INT    ;DS:DX ukazyvayut na proceduru
   MOV  AX,SEG IO_INT       ;
   MOV  DS,AX               ;
   MOV  AL,0BH              ;nomer vektora dlya COM1
   MOV  AH,25H              ;funkciya izmeneniya vektora
   INT  21H                 ;menyaem vektor preryvaniya
;---inicializaciya registra razresheniya preryvaniya (COM1)
   MOV  AX,40H              ;DS ukazyvaet na dannye BIOS
   MOV  DS,AX               ;
   MOV  DX,DS:[0]           ;poluchaem bazovyj adres COM1
   INC  DX                  ;ukazyvaem na registr razresheniya
   MOV  AL,3                ;preryvanij i razreshaem preryvaniya
   OUT  DX,AL               ;priema i peredachi
   POP  DS                  ;vosstanavlivaem registr
;---procedura obrabotki preryvaniya - snachala opredelyaem ego tip
IO_INT      PROC FAR
NEXT_INT:   MOV  DX,BASEADDRESS     ;bazovyj adres
   INC  DX                  ;ukazyvaem na registr identifikacii
   INC  DX                  ;preryvaniya
   IN   AL,DX               ;chitaem ego znachenie
   TEST AL,10B              ;eto preryvanie peredatchika?
   JNZ  TRANSMIT            ;esli da, to na peredachu
RECEIVE:                    ;inache na priem
   .
   .
   JMP SHORT ANOTHER        ;proveryaem net li drugogo preryvaniya

TRANSMIT:                   ;zdes' kod dlya peredachi
   .
   .

;---pered vyhodom, proveryaem net li drugogo preryvaniya
ANOTHER:   MOV  DX,BASEADDRESS       ;bazovyj adres
   INC  DX                  ;ukazyvaem na registr identifikacii
   INC  DX                  ;preryvaniya
   IN   AL,DX               ;chitaem ego znachenie
   TEST AL,1                ;proveryaem bit 1
   JNZ  NEXT_INT            ;esli on ustanovlen, to na nachalo
   MOV  AL,20H              ;inache kod zaversheniya apparatnogo


   OUT  20H,AL              ;preryvaniya
   IRET
IO_INT      ENDP




   |ta tablica soderzhit 32  upravlyayushchih  koda  ASCII, kotorye is-
pol'zuyutsya pri kommunikacii, a takzhe pri rabote printera i drugih
ustrojstv.  Dobavlen takzhe kod  ASCII  127 - DEL (Zaboj), kotoryj
obychno ispol'zuetsya kak upravlyayushchij kod, hotya ego i nel'zya vydat'
s klaviatury s pomoshch'yu sochetaniya Ctrl + klavisha. Primenenie neko-
toryh  kodov,  takih kak vozvrat karetki, invariantno.  No  bol'-
shinstvo drugih upravlyayushchih kodov imeyut shirokij diapazon interpre-
tacii, vo mnogom iz-za otsutstviya sovmestimosti oborudovaniya.

Nomer koda ASCII    Kombinaciya   Mnemo-
10-j   16-j   Simvol    s Ctrl       nika      Naznachenie

 00     00                ^@         NUL      Simvol-razdelitel' (ne imeyushchij znacheniya, poetomu polezen
                                              dlya zaderzhek)
 01     01                ^A         SOH      Nachalo zagolovka. Nachinaet peredachu bloka dannyh ili no-
                                              vogo fajla.
 02     02                ^B         STX      Nachalo teksta. Otmechaet nachalo teksta, sleduyushchego za za-
                                              golovkom dannyh.
 03     03                ^C         ETX      Konec teksta. Mozhet otmechat' nachalo dannyh, sluzhashchih dlya
                                              kontrolya oshibok.
 04     04                ^D         EOT      Konec peredachi. Kod ostanovki, no inogda on prosto otme-
                                              chaet konec fajla.
 05     05                ^E         ENQ      Zapros. Zaprashivaet statusnuyu informaciyu u otdalennoj stancii.
 06     06                ^F         ACK      Podtverzhdenie. Podtverzhdaet uspeshnyj obmen mezhdu stanciyami.
 07     07                ^G         BEL      Zvonok. Iniciiruet zvonok, chtoby privlech' vnimanie.
 08     08                ^H         BS       Vozvrat na shag.
 09     09                ^I         HT       Gorizontal'naya tabulyaciya.
 10     0A                ^J         LF       Perevod stroki.
 11     0B                ^K         VT       Vertikal'naya tabulyaciya.
 12     0C                ^L         FF       Perevod formata.
 13     0D                ^M         CR       Vozvrat karetki.
 14     0E                ^N         SO       Sdvig vyklyuchen. Pereklyuchaet nabor simvolov.
 15     0F                ^O         SI       Sdvig vklyuchen. Pereklyuchaet nabor simvolov.
 16     10                ^P         DLE      Data Link Escape. Modificiruet znachenie sleduyushchih simvolov
                                              (analogichno Esc).
 17     11                ^Q         DC1      Upravlenie ustrojstvom 1. Ispol'zuetsya kak signal XON dlya
                                              udalennoj stancii na peredachu.
 18     12                ^R         DC2      Upravlenie ustrojstvom 2. Signal pereklyucheniya obshchego nazna-
                                              cheniya.


 19     13                ^S         DC3      Upravlenie ustrojstvom 3. Ispol'zuetsya kak signal XOFF dlya
                                              udalennoj stancii dlya prekrashcheniya peredachi.
 20     14                ^T         DC4      Upravlenie ustrojstvom 4. Signal pereklyucheniya obshchego nazna-
                                              cheniya.
 21     15                ^U         NAK      Otricanie. Peredacha neuspeshna.
 22     16                ^V         SYN      Promezhutok sinhronizacii. Ispol'zuetsya mezhdu blokami dannyh
                                              pri sinhronnoj svyazi.
 23     17                ^W         TB       Konec bloka peredachi. Variant ETX.
 24     18                ^X         CAN      Otmena. Obychno signaliziruet ob oshibke peredachi.
 25     19                ^Y         EM       Konec sredy. Signaliziruet o fizicheskom konce istochnika
                                              dannyh.
 26     1A                ^Z         SUB      Podstanovka. Zamenyaet simvoly, kotorye nezakonny ili nevoz-
                                              mozhno vyvesti.
 27     1B                ^[         ESC      Otmechaet posleduyushchie simvoly, kak upravlyayushchuyu posledova-
                                              tel'nost'.
 28     1C                ^/         FS       Razdelitel' fajlov. Otmechaet logicheskuyu granicu mezhdu faj-
                                              lami.
 29     1D                ^]         GS       Razdelitel' grupp. Otmechaet logicheskuyu granicu mezhdu grup-
                                              pami dannyh.
 30     1E                ^^         RS       Razdelitel' zapisej. Otmechaet logicheskuyu granicu mezhdu za-
                                              pisyami dannyh.
 31     1F                ^_         US       Razdelitel' ob®ektov. Otmechaet logicheskuyu granicu mezhdu
                                              ob®ektami dannyh.
 127    7F                net        DEL      Zaboj. Udalyaet drugie simvoly.




   Drajver  ustrojstva eto special'naya programma, kotoraya  uprav-
lyaet obmenom s  periferijnym  ustrojstvom,  takim kak printer ili
diskovyj nakopitel'.  Poskol'ku parametry etih periferijnyh  ust-
rojstv menyayutsya ot proizvoditelya k proizvoditelyu, to raznym pol'-
zovatelyam  programmy mozhet potrebovat'sya dyuzhina razlichnyh drajve-
rov, chtoby on mog rabotat'  na  imeyushchemsya  u  nego  oborudovanii.
Imeetsya 4 sposoba vklyucheniya drajverov ustrojstv v programmu:

   1.   Mozhno pomestit' kod dlya vseh drajverov pryamo v programmu.
Naprimer, chtoby podderzhivat'  razlichnye  printery,  mozhno sozdat'
tablicu upravlyayushchih posledovatel'nostej i iskat' v nej nuzhnyj kod
kazhdyj raz kogda on potrebuetsya.  |tot podhod tratit mnogo pamyati
i mozhet byt' dostatochno medlennym.

   2.  Sozdat' ryad drajverov ustrojstv i potrebovat', chtoby prog-
ramma zagruzhala neobhodimyj v kachestve overleya (t.e. pomeshchat' ego
v   oblast'  programmy,  special'no  ostavlennuyu  dlya  etoj  celi
[1.3.5]).

   3. Sozdat' drajver ustrojstva kak otdel'nuyu programmu, kotoraya
ukazyvaetsya v komandnom fajle, vypolnyaemom pri zagruzke  sistemy.
Programma  zapuskaetsya  i  ustanavlivaet  drajver  ustrojstva kak
programmu obrabotki preryvaniya.  Posle etogo programma zavershaet-
sya, no ostaetsya rezidentnoj v  pamyati,  kak  ob®yasneno v [1.3.4].
Vposledstvii nasha programma ispol'zuet etot drajver cherez  vektor
preryvaniya.

   4. Sozdat' polnocennyj drajver  ustrojstva, kotoryj budet zag-
ruzhat'sya pri starte s pomoshch'yu fajla CONFIG.SYS.  MS DOS podderzhi-
vaet takoj tip drajverov ustrojstv i odnazhdy zagruzhennyj on mozhet
ispol'zovat' vse vozmozhnosti komand DOS, vklyuchaya proverku oshibok.
Special'naya komanda IOCTL (Kontrol' vvoda/vyvoda) pozvolyaet prog-
ramme  uznat' status drajvera i poslat' emu  upravlyayushchuyu  stroku,
pomimo obychnogo potoka dannyh.

   Pervye tri strategii legko  realizuyutsya  s pomoshch'yu informacii,
privedennoj  v ostal'nyh chastyah dannoj knigi.  No ustanavlivaemye
drajvery ustrojstv ochen' slozhny.  Zato kogda on est', to on ochen'
moshchen.   V etom sluchae sistema budet rabotat' s ustrojstvom  nas-
tol'ko zhe tesno, kak  s  klaviaturoj  ili  diskovym  nakopitelem.
Ustrojstvu mozhet byt' prisvoeno imya, naprimer, SERIALPR dlya  pos-
ledovatel'nogo printera, i zatem eto ustrojstvo mozhet byt' otkry-
to  dlya  dostupa iz lyubogo yazyka.  V Bejsike operator  OPEN  "SE-
RIALPR" FOR OUTPUT AS #2 podgotovit  posledovatel'nyj printer dlya
vyvoda.  V yazyke assemblera Vy smozhete poluchit' dostup k printeru
kak s pomoshch'yu  metoda  upravlyayushchego  bloka fajla, tak i s pomoshch'yu
metoda deskriptora fajla, vklyuchaya ochen' moshchnuyu funkciyu IOCTL. Pri
etom pol'zovatel' imeet vozmozhnost' dostupa k ustrojstvu na urov-
ne  operacionnoj sistemy i mozhet prosto vvesti komandu COPY A:MY-
FILE SERIALPR:, chtoby skopirovat' soderzhimoe fajla na printer.
   Ustanavlivaemye drajvery ustrojstv  mogut byt' napisany tol'ko
na  yazyke assemblera.  Oni mogut obsluzhivat' dva tipa  ustrojstv:
simvol'nye i blochnye. |ti imena  opisyvayut edinicy, kotorymi ust-


rojstvo  obrabatyvaet dannye.  Obychno drajvery blochnyh  ustrojstv
obsluzhivayut  diskovye  nakopiteli,  a  drajvery  simvol'nyh - vse
ostal'noe, nachinaya ot posledovatel'nyh printerov i konchaya robota-
mi.  Blochnye ustrojstva  obmenivayutsya blokami dannyh, poetomu oni
zanimayutsya nakopleniem dannyh. Simvol'nye ustrojstva obmenivayutsya
dannymi pobajtno,  poetomu  oni  luchshe  podhodyat  dlya upravlyayushchih
ustrojstv,  a  takzhe dlya ustrojstv, kotorye ne  mogut  obespechit'
vysokuyu skorost' obmena dannymi. Drajvery blochnyh ustrojstv ochen'
slozhny  i zdes' net dostatochno mesta, chtoby ob®yasnit' ih struktu-
ru.  Ochen' redko komu trebuetsya napisat' takoj drajver. Tehniches-
koe  rukovodstvo po MS DOS predostavlyaet vsyu neobhodimuyu informa-
ciyu i soderzhit polnyj primer drajvera virtual'nogo diska v opera-
tivnoj  pamyati.  Vy mozhete prosmotret' etu informaciyu posle  togo
kak izuchite obsuzhdenie drajverov  simvol'nyh ustrojstv, priveden-
noe zdes'.
   Ustanavlivaemye  drajvery ustrojstv besposhchadny k programmists-
kim oshibkam.  Poskol'ku drajvery avtomaticheski zagruzhayutsya siste-
moj  pri zagruzke, to nevozmozhno ispol'zovat' otladchiki dlya vyyav-
leniya prichin nepoladok.  Poetomu bud'te predel'no vnimatel'ny pri
ih napisanii.
   Programma drajvera ustrojstva razbivaetsya na tri chasti, kazhdaya
iz kotoryh obsuzhdaetsya  otdel'no  v  sleduyushchih razdelah.  |to (1)
zagolovok drajvera, kotoryj imenuet ustrojstvo i soderzhit  infor-
maciyu ob ostal'nyh chastyah drajvera, (2) strategiya drajvera, koto-
raya  hranit  informaciyu  ob oblasti dannyh, sozdavaemoj  MS  DOS,
kotoraya nazyvaetya zagolovkom zaprosa, i (3) obrabotchik preryvaniya
ustrojstva, kotoryj i soderzhit kod, upravlyayushchij ustrojstvom.




   Drajvery  ustrojstv  dolzhny  sozdavat'sya  v  vide  COM  fajlov
[1.3.6]. Odnako oni ne yavlyayutsya nastoyashchimi programmami, poskol'ku
u  nih otsutstvuet prefiks programmnogo segmenta.  CHtoby dobit'sya
etogo ne nado vklyuchat' operator ORG  100H v nachale programmy, kak
eto  delaetsya  dlya COM fajlov.  Libo zapishite ORG 0, libo  voobshche
nichego ne pishite.  Drajver  dolzhen  byt' opisan kak dalekaya (far)
procedura,  kak  i v lyuboj programme.  V nizheprivedennom  primere
priveden nachal'nyj kod dlya drajvera ustrojstva s imenem DEVICE12.
Ono  zamenyaet  standartnoe ustrojstvo AUX, ispol'zuemoe  MS  DOS,
prinimaya vyvod funkcii 4 preryvaniya  21H. Ves' drajver ustrojstva
sostoit iz koda etogo razdela vmeste s kodom, privedennom v  sle-
duyushchih dvuh razdelah; pomestite  ih  podryad odin za drugim, chtoby
poluchit' polnuyu programmu.
   Drajver ustrojstva dolzhen nachinat'sya s zagolovka drajvera.  On
imeet dlinu 18 bajtov, razdelennyh  na 5 polej.  Pervoe pole (DD)
vsegda soderzhit znachenie -1 (FFFFFFFFH), i kogda MS DOS zagruzhaet
drajver, to ono zamenyaetsya na startovyj  adres sleduyushchego drajve-
ra.   Takim  obrazom, sistema mozhet iskat' sleduyushchij  drajver  po
cepochke. U poslednego  zagruzhennogo drajvera v etom pole ostaetsya
znachenie -1.
   Vtoroe pole eto bajt atributov drajvera. Imeyut znachenie tol'ko
7 bitov etogo slova:

bit 15   1 = simvol'noe ustrojstvo, 0 = blochnoe ustrojstvo
    14   1 = podderzhivaet IOCTL, 0 = ne podderzhivaet IOCTL


    13   1 = format blokov IBM, 0 = drugoj format blokov
     3   1 = chasy, 0 = ne chasy
     2   1 = nulevoe ustrojstvo, 0 = ne nulevoe ustrojstvo
     1   1 = ustrojstvo standartnogo vyvoda, 0 = net
     0   1 = ustrojstvo standartnogo vvoda, 0 = net

Obychno ustanovlen tol'ko bit 15, ili bity 15 i 14, esli ustrojst-
vo podderzhivaet IOCTL (kak obsuzhdaetsya v [7.2.4]).  Bit 13  usta-
navlivaetsya tol'ko dlya blochnyh ustrojstv.  Ostal'nye bity ispol'-
zuyutsya  dlya  zameny ustrojstv, ispol'zuemyh MS DOS  po  umolchaniyu
(ustrojstvami standartnogo  vvoda  i vyvoda yavlyayutsya klaviatura i
videodisplej;  ustrojstvo chasov ob®edinyaet chasy real'nogo vremeni
s chasami vremeni sutok BIOS; a  nulevoe  ustrojstvo  (NULL) - eto
psevdoustrojstvo, ispol'zuemoe dlya testovyh celej).
   Tret'e i chetvertoe polya soderzhat smeshcheniya dlya procedur strate-
gii i obrabotki preryvaniya, kotorye budut rassmotreny v sleduyushchih
razdelah.  Nakonec, poslednee pole soderzhit imya ustrojstva.   Imya
mozhet soderzhat' do  8  simvolov  i  ono  dolzhno byt' vyravneno po
levomu krayu s zavershayushchimi probelami.  Dlya zameny sushchestvuyushchih  v
DOS ustrojstv, takih kak  LPT1  ili  COM1,  ispol'zujte to zhe imya
ustrojstva, kak v dannom primere.

   Nizkij uroven'.

   V dannom primere sozdaetsya drajver dlya posledovatel'nogo  ust-
rojstva. "DEVICE12" -  imya  fajla,  kotoryj  dolzhen byt' ukazan v
fajle  konfiguracii sisitemy, chtoby etot drajver byl zagruzhen.  V
bajte atributov ustanovlen  tol'ko  bit 15, ukazyvaya chto eto sim-
vol'noe ustrojstvo i chto ono ne podderzhivaet IOCTL.  DEV_STRATEGY
i DEV_INTERRUPT - imena procedur,  obsuzhdaemyh v sleduyushchih razde-
lah.   Ustrojstvo nazvano AUX, s tem chtoby zamenit' obychnoe  ust-
rojstvo MS DOS s etim  imenem.  |to  pozvolyaet ochen' prosto obra-
shchat'sya k etomu ustrojstvu, poskol'ku sistema imeet predopredelen-
nyj nomer fajla dlya obrashcheniya k  ustrojstvu AUX (posledovatel'no-
mu).   V primer vklyuchen nachal'nyj kod dlya drajvera,  opredelyayushchij
ego kak COM programmu.

CSEG      SEGMENT PUBLIC 'CODE'   'ustanavlivaem kodovyj segment
          ORG 0                   'eta stroka neobyazatel'na
          ASSUME CS:CSEG,DS:CSEG,ES:CSEG
DEVICE12  PROC FAR         'drajver eto dalekaya procedura
          DD   0FFFFFFFFH  'adres sleduyushchego drajvera
          DW   8000H       'bajt atributov
          DW   DEV_STATEGY 'adres procedury strategii
          DW   DEV_INTERRUPT  'adres procedury preryvaniya
          DB   'AUX     ' 'imya ustrojstvo (dopolnennoe probelami)




   Procedura  strategii  ustrojstva  trebuet  tol'ko  pyati strok.
Kogda  sistema zagruzhaet ustrojstvo, to ona sozdaet blok  dannyh,
nazyvaemyj zagolovkom zaprosa. On imeet dve funkcii. Vo-pervyh on
sluzhit  oblast'yu  dannyh dlya vnutrennih operacij sistemy.   Bolee
vazhno to, chto zagolovok zaprosa  sluzhit  oblast'yu,  cherez kotoruyu


proishodit  obmen  informaciej mezhdu drajverom i  vyzyvayushchej  ego
programmoj. Naprimer, kogda drajver vyvodit dannye, to emu daetsya
adres dannyh cherez zagolovok zaprosa.  Kogda zhe drajver zavershaet
svoyu rabotu, to on ustanavlivaet  v zagolovke zaprosa bajt statu-
sa,  kotoryj dostupen vyzyvayushchej programme, tem samym davaya  voz-
mozhnost' ej uznat' ob oshibke.
   MS DOS sozdaet zagolovok  zaprosa  pri ustanovke drajvera ust-
rojstva  (kogda  sistema zagruzhaetsya).  Procedura strategii  ust-
rojstva vypolnyaetsya tol'ko odin raz v etot moment. Pri etom ES:BX
ukazyvayut na vnov' sozdannyj zagolovok zaprosa i procedure  nuzhno
prosto skopirovat' ih, chtoby  vposledstvii  on mog byt' obnaruzhen
pri  obrashchenii k drajveru.  Adresa smeshcheniya i segmenta  zagolovka
pomeshchayutsya v dve peremennye. V  sleduyushchem razdele Vy uvidite, chto
pri  obrashchenii k drajveru, pervoe chto on delaet - vosstanavlivaet
znacheniya ES:BX, chtoby mozhno bylo poluchit' informaciyu iz zagolovka
zaprosa.
   Razmer zagolovka zaprosa mozhet menyat'sya, v zavisimosti ot tipa
sdelannogo zaprosa k drajveru (napr.  inicializaciya, vyvod dannyh
ili vozvrat statusa). Odnako pervye 13 bajt zagolovka vsegda odni
i te zhe. Ih format takov:

1. Dlina zagolovka zaprosa (DB).
2. Kod ustrojstva (DB). Opredelyaet nomer dlya blochnyh ustrojstv.
3.   Kod komandy (DB).  Zdes' hranitsya nomer poslednej  poslannoj
drajveru komandy. |ti kody perechisleny v [7.2.3].
4. Status (DW).   Status  ustanavlivaetsya  kazhdyj  raz pri vyzove
drajvera. Esli ustanovlen bit 15, to v mladshih vos'mi bitah naho-
ditsya kod oshibki. Kody oshibok perechisleny v [7.2.3].
5. Rezervnaya oblast' (8 bajtov). Ispol'zuetsya MS DOS.
6. Dannye neobhodimye dlya raboty drajvera (peremennoj dliny).

   Nizkij uroven'.

   Vot 5 strok procedury strategii  ustrojstva. Otmechaem, chto dve
slovnye  peremennye, hranyashchie znacheniya ES i BX, sleduyut za  inst-
rukciej RET, kak i polozheno v formate COM.

DEV_STRATEGY:   MOV  CS:KEEP_ES,ES
                MOV  CS:KEEP_BX,BX
                RET
KEEP_CS         DW ?
KEEP_BX         DW ?




   Drajver ustrojstva nachinaetsya s  dvuh porcij koda, privedennyh
v  predydushchih razdelah.  Za nimi dolzhna sledovat' sootvetstvuyushchaya
procedura obrabotki preryvaniya. Na samom dele, eto neverno, nazy-
vat'  etu proceduru proceduroj obrabotki preryvaniya, tak kak  ona
vovse ne obsluzhivaet preryvanie i zavershaetsya obychnoj instrukciej
RET.
   Imeetsya  13 tipov funkcij, kotorye mozhet vypolnyat'  ustanavli-
vaemyj drajver ustrojstva.  Kogda drajver vyzyvaetsya funkciej DOS
(skazhem funkciej  3FH  preryvaniya  21H,  kotoraya chitaet dannye iz


fajla ili ustrojstva), to funkciya pomeshchaet kodovyj nomer ot 1  do
13 v odnobajtnoe  pole  po  smeshcheniyu  2  v zagolovke zaprosa (dlya
vvoda - kodovyj nomer 5).  Zatem upravlenie peredaetsya  procedure
obrabotki preryvaniya  drajvera,  adoes  kotoroj  opredelyaetsya pri
prosmotre  zagolovka  drajvera [7.2.1].  |ta  procedura v  pervuyu
ochered' vosstanavlivaet ES:BX, s tem chtoby oni ukazyvali na zago-
lovok  zaprosa, a zatem chitaet kodovyj nomer komandy.   Po  etomu
kodu procedura  obrabotki  preryvaniya  vyzyvaet nuzhnuyu proceduru,
kotoraya  vypolnit trebuemuyu funkciyu.  Procedura ishchetsya s  pomoshch'yu
13-slovnoj tablicy,  soderzhashchej  smeshcheniya  dlya  13 tipov funkcij.
Funkcii vsegda perechislyayutsya v sleduyushchem poryadke:

   1. INITIALIZE (inicializaciya)
   2. CHECK_MEDIA (proverka nositelya)
   3. MAKE_BPB
   4. IOCTL_IN
   5. INPUT_DATA (vvod dannyh)
   6. NONDESTRUCT_IN
   7. INPUT_STATUS (status vvoda)
   8. CLEAR_INPUT (ochistka vvoda)
   9. OUTPUT_DATA (vyvod dannyh)
  10. OUTPUT_VERIFY (proverka vyvoda)
  11. OUTPUT_STATUS (status vyvoda)
  12. CLEAR_OUTPUT (ochistka vyvoda)
  13. IOCTL_OUT

   Posle  zaversheniya  procedury, procedura  obrabotki  preryvaniya
zavershaetsya instrukciej RET i  upravlenie vozvrashchaetsya v vyzyvayu-
shchuyu programmu. Drajver ustrojstva mozhet vklyuchat' kod dlya obrabot-
ki tol'ko nekotoryh funkcij, v  zavisimosti  ot ustrojstva i tre-
buemoj  stepeni kontrolya oshibok i upravleniya ustrojstvom.  Nomera
funkcij, dlya kotoryh ne  napisany  procedury,  dolzhny zavershat'sya
vyhodom iz drajvera bez vypolneniya chego-libo.  V etom sluchae nado
tol'ko pered  vyhodom  ustanovit'  bity  15, 8, 1 i 0 v zagolovke
zaprosa, chtoby informirovat' vyzyvayushchuyu zadachu, chto byla zatrebo-
vana nesushchestvuyushchaya  funkciya  (bit  15  indiciruet  oshibku, bit 8
pokazyvaet, chto drajver rabotaet normal'no, a bity 0 i 1 dayut kod
oshibki 3, chto sootvetstvuet "neizvestnoj komande").
   No odna funkciya dolzhna  prisutstvovat'  vo vseh drajverah ust-
rojstv, i eto funkciya nomer 1 - inicializaciya.  |ta funkciya avto-
maticheski vypolnyaetsya pri zagruzke drajvera, a zatem net. Odna iz
vazhnyh  zadach,  vypolnyaemaya etoj  proceduroj,  sostoit  ustanovke
adresa konca drajvera v chetyreh  bajtah, nachinayushchihsya so smeshcheniya
14 v zagolovke zaprosa. V nizheprivedennom primere konec programmy
otmechen metkoj eop:. Krome etoj  zadachi,  procedura inicializacii
dolzhna  takzhe  vypolnit' vsyu neobhodimuyu dlya  dannogo  ustrojstva
inicializaciyu. Na ris.  7-4 pokazana struktura drajvera ustrojst-
va.
   Kakie  iz  ostavshihsya 12-ti funkcij budut  vklyucheny v  drajver
ustrojstva zavisit ot togo, chto drajver dolzhen delat'. Nekotorye,
takie  kak  CHECK_MEDIA  i MAKE_BPB, otnosyatsya  tol'ko k  blochnym
ustrojstvam  (oni  ustanavlivayut   tip  diska,  razmer sektorov i
t.d.).   Dlya  simvol'nyh ustrojstv naibolee vazhnymi yavlyayutsya  dve
funkcii: INPUT_DATA i  OUTPUT_DATA  (otmetim, chto eti imena nesu-


shchestvenny  - vazhna poziciya v tablice funkcij, kotoraya neizmenna).
V oboih sluchayah zagolovok zaprosa imeet sleduyushchuyu strukturu:

13 bajtov    standartnyj format zagolovka zaprosa
 1 bajt      bajt opisaniya sredy (tol'ko dlya blochnyh ustrojstv)
 4 bajta     smeshchenie/segment bufera obmena dannyh
 2 bajta     chislo bajtov, kotoroe nado peredat'
 2 bajta     startovyj nomer sektora (tol'ko dlya blochnyh)

V nizheprivedennom primere ispol'zuetsya funkciya vyvoda. Procedura,
vypolnyayushchaya  vyvod poluchaet iz zagolovka zaprosa adres bufera,  v
kotorom nahodyatsya vyvodimye dannye  (smeshchenie 14). Ona takzhe schi-
tyvaet  chislo bajtov, kotoroe nado vyvesti (smeshchenie 18).   Kogda
procedura zavershit vyvod dannyh, to ona ustanovit slovo statusa v
zagolovke zaprosa (smeshchenie 3) i vozvratit upravlenie.  Esli ope-
raciya uspeshna, to  nado  ustanovit'  bit  8 slova statusa. Drugie
vozmozhnosti budut obsuzhdeny pozdnee.

   Nizkij uroven'.

   V  dannom  primere privedena obshchaya forma  procedury  obrabotki
preryvaniya, ne vklyuchaya real'nogo koda, upravlyayushchego ustrojstvom.

;---inicializaciya obrabotchika preryvaniya ustrojstva
DEV_INTERRUPT:  PUSH ES     ;sohranyaem registry
                PUSH DS
                PUSH AX
                PUSH BX
                PUSH CX
                PUSH DX
                PUSH SI
                PUSH DI
                PUSH BP
   MOV  AX,CS:KEEP_ES    ;ES:BX ukazyvayut na zagolovok zaprosa
   MOV  ES,AX            ;
   MOV  BX,CS:KEEP_BX    ;
   MOV  AL,ES:[BX]+2     ;poluchaem kod komandy iz zagolovka
   SHL  AL,1             ;umnozhaem na 2 (t.k. tablica slovnaya)
   SUB  AH,AH            ;obnulyaem AH
   LEA  DI,FUNCTIONS     ;DI ukazyvaet na smeshchenie do tablicy
   ADD  DI,AX            ;dobavlyaem smeshchenie v tablice
   JMP  WORD PTR [DI]    ;perehodim na adres iz tablicy

FUNCTIONS       LABEL  WORD  ;eto tablica funkcij
   DW   INITIALIZE
   DW   CHECK_MEDIA
   DW   MAKE_BPB
   DW   IOCTL_IN
   DW   INPUT_DATA
   DW   NONDESTRUCT_IN
   DW   INPUT_STATUS
   DW   CLEAR_INPUT
   DW   OUTPUT_DATA
   DW   OUTPUT_VERIFY


   DW   OUTPUT_STATUS
   DW   CLEAR_OUTPUT
   DW   IOCTL_OUT

;---vyhod iz drajvera, esli funkciya ne podderzhivaetsya
CHECK_MEDIA:
MAKE_BPB:
IOCTL_IN:
INPUT_DATA:
NONDESTRUCT_IN:
INPUT_STATUS:
CLEAR_INPUT:
OUTPUT_VERIFY:
OUTPUT_STATUS:
CLEAR_OUTPUT:
IOCTL_OUT:
   OR   ES:WORD PTR [BX]+3,8103H   ;modificiruem status
   JMP  QUIT

;---procedury dlya dvuh podderzhivaemyh kodov
INITIALIZE:   LEA  AX,E_O_P      ;smeshchenie konca programmy v AX
   MOV  ES:WORD PTR [BX]+14,AX   ;pomeshchaem ego v zagolovok
   MOV  ES:WORD PTR [BX]+16,CS   ;
    .
   (zdes' idet inicializaciya ustrojstva)
    .
   JMP  QUIT

OUTPUT_DATA:  MOV  CL,ES:[BX]+18 ;poluchaem chislo simvolov
   CBW  CX                       ;CX ispol'zuem kak schetchik
   MOV  AX,ES:[BX]+16            ;poluchaem adres bufera dannyh
   MOV  DS,AX                    ;
   MOV  DX,ES:[BX]+14            ;
    .
   (zdes' idut operacii po vyvodu)
    .
   JMP  QUIT

;---vyhodim, modificiruya bajt statusa v zagolovke zaprosa
QUIT:   OR   ES:WORD PTR [BX]+3,100H  ;ustanavlivaem bit 8
   POP BP                    ;vosstanavlivaem registry
   POP DI                    ;
   POP SI                    ;
   POP DX                    ;
   POP CX                    ;
   POP BX                    ;
   POP AX                    ;
   POP DS                    ;
   POP ES                    ;
   RET
E_O_P:              ;metka konca programmy
DEVICE12     ENDP
CSEG         ENDS
             END    DEVICE12


   Pered vozvratom drajver ustanavlivaet slovo statusa v zagolov-
ke zaprosa.  V dannom primere eto delaetsya v dvuh mestah, v zavi-
simosti ot togo vyzyvalas'  funkciya  obespechivaemaya drajverom ili
net. |ti stroki vyglyadyat tak: OR ES:WORD PTR [BX]+3,XXXXH. Znache-
nie bitov XXXX sleduyushchee:

   bity 0-7   kod oshibki (esli bit 15 = 1)
   bit    8   ustanavlivaetsya v 1, kogda funkciya zavershena
   bit    9   ustanavlivaetsya v 1, kogda drajver zanyat
 bity 10-14   zarezervirovany MS DOS
   bit   15   ustanavlivaetsya pri vozniknovenii oshibki

Mladshij bajt etogo  slova  soderzhit  sleduyushchie  kody oshibok, esli
ustanovlen bit 15, indiciruyushchij oshibku:

   0    popytka zapisi na zashchishchennoe ot zapisi ustrojstvo
   1    neizvestnoe ustrojstvo
   2    ustrojstvo ne gotovo
   3    neizvestnaya komanda
   4    oshibka proverki po kontrol'noj summe
   5    nevernaya dlina zaprosa k ustrojstvu
   6    oshibka poiska
   7    neizvestnyj nositel'
   8    sektor ne najden
   9    net bumagi v printere
   A    oshibka zapisi
   B    oshibka chteniya
   C    obshchaya oshibka




   Drajver ustrojstva ustanavlivaetsya putem vklyucheniya imeni goto-
voj programmy v fajl konfiguracii sistemy.  Dlya ustanovki probnoj
programmy pomestite  v  fajl  CONFIG.SYS  stroku  DEVICE  = DEVI-
CE12.COM.   Zatem perezagruzite sistemu dlya  ustanovki  drajvera.
Esli mashina ne budet  zagruzhat'sya, to skoree vsego imeetsya oshibka
v kode inicializacii drajvera.
   Posle togo kak drajver ustanovlen, dlya dostupa k nemu pol'zuj-
tes' obychnymi funkciyami MS  DOS  preryvaniya  21H.   Kakie funkcii
mozhno  ispol'zovat' zavisit ot togo, zamenyaet li ustrojstvo stan-
dartnoe ustrojstvo DOS (kak v privedennom primere) ili ono dobav-
lyaetsya  kak sovershenno novoe ustrojstvo.  Dlya zameny standartnogo
posledovatel'nogo ustrojstva,  nazovite  drajver  AUX, posle chego
funkcii  3 [7.1.7] i 4 [7.1.6] preryvaniya 21H budut  osushchestvlyat'
sootvetstvenno vvod i  vyvod.   Esli  ustrojstvo parallel'noe, to
nazovite  ego  PRN, posle chego funkciya 5 [6.3.1]  budet  vyvodit'
dannye na printer.  Drugoj  vozmozhnost'yu  yavlyaetsya  ispol'zovanie
funkcii 3FH [5.4.4] dlya vvoda i [5.4.3] dlya vyvoda. V etom sluchae
ispol'zujte nomer fajla 3 - dlya posledovatel'nogo  ustrojstva i 4
- dlya parallel'nogo.  Napominaem, chto pri ispol'zovanii predopre-
delennyh nomerov fajla net neobhodimosti otkryvat' ustrojstvo.
   Esli ustrojstvo ne zamenyaet  odno  iz standartnyh ustrojstv MS
DOS (t.e.  esli ono ne nazvano odnim iz rezervnyh slov, takim kak
PRN, AUX i t.d.), to Vy mozhete otkryt' ustrojstvo s pomoshch'yu odnoj


iz funkcij dlya otkrytiya fajla.  Vy mozhete ispol'zovat' kak  metod
dostupa s pomoshch'yu upravlyayushchego  bloka fajla, tak i metod deskrip-
tora fajla, hotya poslednij predpochtitel'nee.  CHtoby byt'  uveren-
nym, chto Vy po oshibke ne  otkroete diskovyj fajl, pomestite nomer
fajla v BX, 0 - v AL, posde chego vypolnite funkciyu 44H preryvaniya
21H. |to funkciya IOCTL i esli  bit 7 znacheniya, vozvrashchaemogo v DL
ustanovlen, to drajver ustrojstva zagruzhen.
   IOCTL  trebuet,  chtoby v bajte atributov drajvera  byla  soot-
vetstvuyushchaya ustanovka bitov i chtoby po krajnej mere osnovy proce-
dury  obrabotki IOCTL imelis' v procedure obrabotchika  preryvaniya
drajvera. Funkciya IOCTL imeet 8  podfunkcij, pronumerovannyh ot 0
do  7, pri etom sootvetstvuyushchij kodovyj nomer pomeshchaetsya v AL pri
vyzove funkcii:

   0    Vozvratit' informaciyu ob ustrojstve v DX
   1    Ustanovit' informaciyu ob ustrojstve, ispol'zuya DL (DH=0)
   2    Schitat' CX bajtov ot drajvera ustrojstva cherez upravlya-
        shchij kanal i pomestit' ih nachinaya s DS:DX
   3    Zapisat' CX bajtov v drajver ustrojstva cherez upravlyayushchij
        kanal, vzyav ih nachinaya s DS:DX
   4    To zhe, chto i 2, no ispol'zovat' nomer nakopitelya v BL,
        gde 0 = nakopitel' po umolchaniyu, 1 = A i t.d.
   5    To zhe, chto i 3, no ispol'zovat' nomer nakopitelya kak v 5
   6    Poluchit' status vvoda
   7    Poluchit' status vyvoda

   V  otvet vozvrashchaetsya razlichnaya informaciya, v  zavisimosti  ot
togo, kakaya funkciya vyzvana. Dlya  podfunkcij 0 i 1 znachenie bitov
registra  DX sleduyushchee (pri uslovii, chto bit 7 = 1, chto oznachaet,
chto dostup poluchen k ustrojstvu, a ne k fajlu):

   0    1 = ustrojstvo konsol'nogo vvoda
   1    1 = ustrojstvo konsol'nogo vyvoda
   2    1 = nulevoe ustrojstvo
   3    1 = ustrojstvo chasy
   4    rezerv
   5    1 = net proverki na Ctrl-Z, 0 = est' proverka na Ctrl-Z
   6    1 = ne konec fajla, 0 = konec fajla
   7    1 = ustrojstvo, 0 = diskovyj fajl
8-13    rezerv
  14    1 = esli mozhno ispol'zovat' podfunkcii 2 i 3, 0 = nel'zya
  15    rezerv

   Podfunkcii 2-5 pozvolyayut  programme  i ustrojstvu obmenivat'sya
proizvol'nymi  upravlyayushchimi strokami.  |to  pozvolyaet  peredavat'
upravlyayushchie soobshcheniya  otdel'no  ot  osnovnogo potoka dannyh, chto
sushchestvenno uproshchaet delo.  Pri vozvrate AX budet soderzhat' chislo
peredannyh bajtov.  Podfunkcii 6-7 pozvolyayut programme proverit',
gotovo  li ustrojstvo dlya vvoda ili vyvoda.  Dlya  ustrojstv v  AL
vozvrashchaetsya FF, esli  ustrojstvo  gotovo i 0, esli net.  Pri is-
pol'zovanii s otkrytym fajlom (bit 7 = 0) v AL vozvrashchaetsya FF do
teh por, poka ne budet dostitgnut konec fajla.
   Otmetim, chto v Bejsike 3.0 dobavleny operatory IOCTL i IOCTL$.
Oni pozvolyayut bejsikovskoj programme, sootvetstvenno, posylat'  i


prinimat' upravlyayushchie stroki ot drajvera ustrojstva, kotoroe bylo
predvaritel'no  otkryto operatorom OPEN.  Vyhodnaya stroka  dolzhna
byt' zaklyuchena v kavychki, kak v IOCTL #3,"...". Podobnym obrazom,
A$ = IOCTL$(3) prinimaet informaciyu o statuse cherez IOCTL.




   Ustrojstva mogut oshibat'sya po odnoj iz treh prichin. Ustrojstvo
mozhet byt' fizicheski povrezhdeno  ili  nahodit'sya ne v tom sostoya-
nii.  Mozhet byt' plohim programmnoe obespechenie, upravlyayushchee ust-
rojstvom. I, nakonec, programma mozhet poslat' ustrojstvu nedopus-
timyj  zapros (naprimer, popytka pisat' na nakopitel', gde  naho-
ditsya disketa zashchishchennaya ot zapisi). MS DOS obnaruzhivaet i anali-
ziruet  bol'shinstvo takih oshibok i obespechivaet  vozmozhnosti  dlya
vosstanovleniya.

   Vysokij uroven'.

   Interpretator  Bejsika  obnaruzhivaet   mnogie  oshibki, vklyuchaya
oshibki  drajverov ustrojstv.  Pri obnaruzhenii oshibki vozvrashchaetsya
kod oshibki i esli ne  predusmotrena  programma vosstanovleniya pri
oshibkah,  to programma ostanavlivaetsya.  Odnako mozhno  ustanovit'
obrabotku oshibok, s tem chtoby kogda proishodit kriticheskaya oshibka
Bejsik  avtomaticheski perehodil na proceduru  vosstanovleniya  pri
sboyah, kotoruyu Vy sozdali. Procedura mozhet proanalizirovat' kod i
opredelit' v kakoj stroke programmy proizoshla oshibka.  Posle togo
kak eto sdelano, programma mozhet prinyat' mery po ustraneniyu oshib-
ki, libo s pomoshch'yu pol'zovatelya, libo vypolnyaya druguyu chast' prog-
rammy.  Posle togo, kak eta  procedura zavershena, programma mozhet
prodolzhit'  vypolnenie s lyubogo mesta, s kotorogo Vy zahotite  (s
nekotorymi ogranicheniyami). Kod  dlya tshchatel'nogo analiza oshibochnyh
situacij mozhet sushchestvenno uvelichit' razmer programmy.   Otmetim,
chto kompilyatora Bejsika dazhe  minimal'nye proverki na oshibki pot-
rebuyut  dopolnitel'no  po ne menee chem 4 bajta na  kazhduyu  stroku
programmy.
   CHtoby razreshit' obrabotku  oshibok v Bejsike pomestite v nachale
programmy  stroku ON ERROR GOSUB n, gde n eto nomer stroki  prog-
rammy, v kotoroj nachinaetsya procedura obrabotki oshibok.  Pri voz-
niknovenii  kriticheskoj oshibki upravlenie budet peredano  na  etu
stroku. V nachale  procedury  pomestite  ryad strok vida IF ERR = n
THEN  nomerstroki,  gde n - nomer oshibki, vzyatyj iz prilozheniya  k
rukovodstvu po Bejsiku, soderzhashchemu  soobshcheniya ob oshibkah. Nomera
strok v etih operatorah sootvetstvuyut nachalu koda, obrabatyvayushche-
go dannuyu konkretnuyu oshibku.  |ti chasti mogut byt' v svoyu ochered'
razbity  na  kuski ryadom operatorov IF ERL = n THEN  nomerstroki.
ERL vozvrashchaet nomer stroki, v kotoroj proizoshla oshibka, pozvolyaya
procedure vosstanovleniya tochno opredelit' oshibochnoe mesto.
   Posle togo kak procedura vosstanovleniya zavershila svoyu  rabotu
nado ispol'zovat'  operator  RESUME  dlya vozvrata upravleniya v tu
stroku, gde proizoshla oshibka.  Za etim operatorom mozhet sledovat'
nomer, v etom sluchae upravlenie  budet  peredano na stroku s uka-
zannym  nomerom.  Odnako, imejte vvidu, chto  nel'zya  ispol'zovat'
RESUME dlya perehoda v tochku  programmy, kotoraya nahoditsya za pre-
delami procedury, v kotoroj proizoshla oshibka. Esli vosstanovlenie


posle oshibki nevozmozhno, no neobhodimo, chtoby programma prodolzhi-
la  svoyu rabotu, to napishite RESUME NEXT i upravlenie budet pere-
dano na stroku, sleduyushchuyu za toj, v kotoroj proizoshla oshibka. Vot
obshchaya struktura procedury vosstanovleniya v Bejsike:

100 ON ERROR GOSUB 5000   'razreshaem obrabotku oshibok
 .
 .
5000 IF ERR = 61 THEN 5100  'disk polon
5010 IF ERR = 71 THEN 5200  'disk ne gotov
 .
 .
5100 IF ERL = 2080 THEN 5120   'gde proizoshla oshibka?
5110 BEEP: PRINT "Disk in drive B: is full": RESUME
5120 BEEP: PRINT "Disk in drive A: is full": RESUME
 .
5200 BEEP: PRINT "A disk drive is not ready"
5210 PRINT "Strike any key when corrected"
5220 IF INKEY$ = "" THEN 5220    'ozhidaem nazhatiya klavishi
5230 RESUME ERL - 10             'pytaemsya povtorit' operaciyu

   V Bejsike 3.0 vvedeny instrukcii ERDEV i ERDEV$.  Obe oni poz-
volyayut poluchit' peremennye  tol'ko  dlya chteniya ot preryvaniya 24H,
obrabatyvayushchego  kritichekie  oshibki.  Z% = ERDEV vozvrashchaet v  Z%
slovo statusa, v kotorom starshij bajt soderzhit 13-15 bity atribu-
ta  zagolovka ustrojstva, a mladshij bajt - kod oshibki  preryvaniya
24H.  Z$ = ERDEV$ pomeshchaet v Z$ 8-bajtnoe imya ustrojstva dlya sim-
vol'nyh  ustrojstv  i 2-bajtnyj ukazatel' nakopitelya dlya  blochnyh
ustrojstv.

   Nizkij uroven'.

   Inogda drajvery ustrojstv soderzhat takie ser'eznye oshibki, chto
programma prosto ne mozhet prodolzhat'sya, poka oni ne budut isprav-
leny. Kogda takie oshibki proishodyat, to sistema vyzyvaet obrabot-
chik  kriticheskih  oshibok.  On mozhet vstupat' v dejstvie  kak  dlya
standartnyh ustrojstv, tak i dlya ustanovlennyh drajverov. Pol'zo-
vatel'  naibolee chasto stalkivaetsya s nim, kogda pytaetsya  proiz-
vesti diskovuyu operaciyu s  diskovodom, u kotorogo otkryta dverca.
V  etom  sluchae  poyavlyaetsya soobshchenie: "Not ready  error  reading
drive A - Abort, Retry, Ignore?"
   Obrabotchik kriticheskih oshibok  mozhet  byt' perepisan, chtoby on
luchshe  obrabatyval ustrojstva, dlya kotoryh Vy sozdali  ustanavli-
vaemye drajvery. Vektor  preryvaniya  24H ukazyvaet na standartnuyu
proceduru MS DOS, no Vy mozhete perenapravit' vektor na svoyu  pro-
ceduru. Pri vyzove etoj  procedury starshij bit AH soderzhit 0 esli
oshibka  proizoshla na blochnom ustrojstve i 1, esli na  simvol'nom.
BP:SI ukazyvayut na zagolovok drajvera vinovnogo ustrojstva, koto-
ryj mozhet dat' dopolnitel'nuyu informaciyu.  Vosem' bajtov, nachinaya
so smeshcheniya AH v zagolovke soderzhat  imya ustrojstva, a obrabotchik
kritichekih  oshibok pomeshchaet kod oshibki dlinoj v slovo v DI.   Vot
kodovye nomera (oni ne predstavlyayut bitovyh pozicij):


   Kod           Problema

    0      popytka pisat' na disk, zashchishchennyj ot zapisi
    1      neizvestnoe ustrojstvo
    2      nakopitel' ne gotov
    3      neizvestnaya komanda
    4      oshibka obmena dannymi
    5      nevernaya dlina zaprosa
    6      oshibka poiska

    7      neizvestnyj tip nositelya
    8      sektor ne najden
    9      net bumagi v printere
    A      oshibka pri zapisi
    B      oshibka pri chtenii
    C      obshchaya oshibka

V sluchae diskovoj oshibki AL soderzhit nomer nakopitelya, na kotorom
proizoshla  oshibka (0 = A, 1 = B i t.d.), a bity 2-0 AH indiciruyut
tip oshibki. Bit 0 ustanavlivaetsya, esli oshibka proizoshla vo vremya
operacii  zapisi, i sbrasyvaetsya - esli pri chtenii.  Bity 2-1 so-
derzhat informaciyu o tom, v  kakom  meste  diska proizoshla oshibka,
davaya  00  - dlya nachal'nyh sektorov DOS, 01 - dlya FAT,  10 -  dlya
kataloga i 11 - dlya vsego ostal'nogo diska.
   Imeetsya tri sposoba, kotorymi  programma  mozhet vosstanovit'sya
posle kriticheskoj oshibki:

1.  Mozhno poprosit' pol'zovatelya ustranit' prichinu oshibki (napri-
mer, zakryt' dvercu  nakopitelya),  posle chego sistema predostavit
ustrojstvu vozmozhnost' povtorit' operaciyu.
2.  Upravlenie mozhet byt' vozvrashcheno instrukcii, sleduyushchej za INT
21H, kotoraya sdelala popytku obratit'sya k drajveru.
3. Programma mozhet zavershit'sya i vernut' upravlenie sisteme.

   Vasha procedura obrabotki  oshibok  mozhet vosstanovit' situaciyu,
vydav  instrukciyu  IRET,  posle togo, kak ona pomestila  0 v  AL,
chtoby ignorirovat' oshibku, 1  -  chtoby  povtorit'  operaciyu i 2 -
chtoby zavershit' programmu.  Esli Vy hotite, chtoby Vasha  procedura
provela vosstanovlenie sama, to  ona dolzhna vosstanovit' registry
vypolnyaemoj  programmy  iz steka, a zatem udalit' so  steka  vse,
krome poslednih treh slov. Posle  etogo instrukciya IRET vozvratit
upravlenie  programme, hotya sama sistema ostanetsya v nestabil'nom
sostoyanii do teh por, poka ona ne sdelaet vyzov funkcii s nomerom
bol'shim, chem 12.  Vot konfiguraciya steka (nachinaya sverhu do niza)
kogda vyzyvaetsya obrabotchik kriticheskih oshibok:

Adres vozvrata obrabotchika oshibok:  IP, CS, flagi

Pol'zovatel'skie registry zadachi,   AX, BX, CX, DX, SI, DI, BP,
iz kotoroj byl vyzvan drajver:      DS, ES, IP, CS, flagi

   MS DOS obrabatyvaet takzhe mnogie  nekriticheskie  oshibki.  Syuda
vklyuchayutsya  kody oshibok, kotorye mogut vozvrashchat'sya v  registrah,
kogda vyzyvalas' funkciya DOS. |ti kody obsuzhdayutsya v dannoj knige


v  teh  mestah, v kotoryh  opisyvayutsya  sootvetstvuyushchie  funkcii.
Odnako imejte vvidu, chto  nachinaya  s versii 3.0 MS DOS vozvrashchaet
rasshirennye  kody oshibok dlya funkcij, ispol'zuyushchih FCB ili  desk-
riptory fajlov.  Kogda pri vypolnenii odnoj iz etih funkcij usta-
navlivaetsya flag perenosa, to v AX vozvrashchaetsya obychnyj kod oshib-
ki. Dopolnitel'nyj rasshirennyj kod dostupen cherez preryvanie 59H,
esli v BX pomestit' 0.  |ta funkciya soobshchaet takzhe o  kriticheskih
oshibkah i ona mozhet byt'  ispol'zovana iz obrabotchika kriticheskih
oshibok, vyzyvaemogo cherez preryvanie 24H.
   Funkciya  pomeshchaet  v AX kod oshibki, vzyatyj iz obychnogo  spiska
znakomyh kodov oshibok (naprimer, "nedostatochno  pamyati") ili odin
iz novyh kodov (naprimer, "ogranichenie dostupa" dlya  mnogopol'zo-
vatel'skoj sistemy).  BH  vozvrashchaet  kod klassa oshibki, ukazyvaya
kakogo  tipa  oshibka proizoshla.  Naprimer, kod 1  ukazyvaet,  chto
ischerpany resursy, t.e.  chto  pamyat',  fajlovye bufera ili chto-to
eshche  izrashodovano.  Drugie klassy mogut ukazyvat' na programmnye
oshibki, problemy s nositelyami, formatirovaniem i t.d. BL soderzhit
kod, predpolagayushchij dejstvie dlya vosstanovleniya, takoe kak  "pov-
torit'", "prekratit'" ili "zaprosit' u pol'zovatelya". Nakonec, CH
vozvrashchaet chislo,  opredelyayushchee  mesto  gde voznikli problemy: na
blochnom ustrojstve, na simvol'nom, v pamyati?
   Dannye dlya etih kodov oshibok ves'ma obshirny. Polnuyu informaciyu
o nih sm.  v  Tehnicheskom  rukovodstve  po MS DOS 3.0.  Poskol'ku
predpolagaetsya,  chto MS DOS 3.0 ne budet ispol'zovat'sya na  mashi-
nah, bolee rannih, chem AT, to  ispol'zovanie etih kodov ogranichi-
vaet sovmestimost' Vashih programm.  Tem ne menee, nabor procedur,
prednaznachennyj tol'ko dlya MS  DOS  3.0  mozhet dopolnyat'sya poverh
obychnyh  procedur obrabotki oshibok.  V [1.1.3] pokazano kak prog-
ramma mozhet opredelit' versiyu MS DOS, v kotoroj ona rabotaet.
   Nakonec, imejte vvidu, chto process mozhet peredavat' kod zaver-
sheniya vyzvavshemu ego processu. Termin process otnositsya k vzaimo-
dejstvuyushchim programmam.  Naprimer, kogda odna programma zagruzhaet
i  zapuskaet druguyu s pomoshch'yu funkcii EXEC, to zapuskaemaya  prog-
ramma nazyvaetsya potomkom, a  zapuskayushchaya  programma - roditelem.
Roditelyu mozhet  potrebovat'sya  informaciya  o  tom, kak zavershilsya
potomok.  CHtoby ispol'zovat' etu vozmozhnost', pomestite  zhelaemyj
kod zaversheniya v AL i  vypolnite  funkciyu  4CH preryvaniya 21H dlya
zaversheniya programmy. Kogda upravlenie budet vozvrashcheno roditelyu,
to on vypolnit funkciyu 4DH preryvaniya 21H (bez vhodnyh registrov)
i  v  AL budet poluchen kod zaversheniya, kotoryj mozhet  zatem  byt'
proanalizirovan. Krome togo, AH budet soderzhat' informaciyu o tom,
kak  zavershilsya  potomok: 0 - dlya normal'nogo zaversheniya, 1 -  po
Ctrl-Break, 2 - po kriticheskoj oshibke  ustrojstva i 3 - s pomoshch'yu
funkcii 31H, ostavlyayushchej zadachu rezidentnoj.
   Esli programma zavershilas' s pomoshch'yu etoj funkcii (a ne 20H  -
sm. obsuzhdenie v [1.3.4]),  to  MS  DOS  poluchaet kod vyhoda i on
mozhet byt' vklyuchen v obrabotku komandnym fajlom s pomoshch'yu  podko-
mandy IF. |ta  podkomanda  pozvolyaet  uslovnoe  isklyuchenie drugih
komand iz komandnogo fajla.  Kod vyhoda rassmatrivaetsya kak nomer
ERRORLEVEL i uslovnye operacii vypolnyayutsya v zavisimosti ot togo,
bol'she on ili net opredelennogo chisla. S pomoshch'yu etoj vozmozhnosti
komandnye fajly mogut prekrashchat'  obrabotku i vyvodit' soobyushchenie
o  vozniknovenii  oshibki v odnoj iz zapushchennyh  programm.   Bolee
podrobnaya informaciya privedena v razdele  "Komandy paketnoj obra-
botki" rukovodstva po operacionnoj sisteme.




   Imeetsya  ogromnoe  kolichestvo ustrojstv vvoda/vyvoda,  kotorye
mogut byt' prisoedineny k IBM PC,  vklyuchaya mysh', dzhojstik, grafo-
postroiteli  i t.d.  V dannom razdele obsuzhdayutsya tol'ko te  ust-
rojstva, kotorye special'no  podderzhivayutsya oborudovaniem IBM PC.
Syuda  otnosyatsya  kassetnye  magnitofony, svetovoe  pero i  drugie
ustrojstva, kotorye mogut byt'  prisoedineny  cherez igrovoj port.
Adresa  portov,  otnosyashchiesya k drugim ustrojstvam, obsuzhdayutsya  v
drugih razdelah etoj knigi, otnosyashchihsya imenno k dannym ustrojst-
vam.   Raspredelenie  adresov portov v osnovnom odno i to zhe  dlya
vseh tipov IBM PC:

Adres porta        Funkciya

  00-0F      mikroshema DMA 8237 (ne dlya PCjr)
  20-2F      mikroshema preryvanij 8259 (AT kontroller #1: 20-3F)
  40-4F      mikroshema tajmera 8253/8254
  60-6F      mikroshema PPI 8255 (AT ispol'zuet tol'ko adresa
             klaviatury
  70-7F      chasy real'nogo vremeni (tol'ko AT)
  80-83      registry stranic DMA (ne dlya PCjr)
  A0-BF      mikroshema preryvanij #2 (tol'ko AT)
  C0-C7      mikroshema zvuka SN76496 (tol'ko PCjr)
  F0-FF      PCjr - kontroller NGMD, AT - upravlenie matematiche-
             skim soprocessorom
1F0-1F8      fiksirovannyj disk AT
200-20F      igrovoj adapter
278-27F      AT kommunikacionnyj port #2
2F8-2FF      kommunikacionnyj port COM2 (COM1 dlya PCjr)
320-32F      fiksirovannyj disk XT
378-37F      adapter parallel'nogo printera dlya PC, XT, AT
3B0-3BF      monohromnyj/parallel'nyj adaptery (ne dlya PCjr)
3D0-3DF      cvetnoj graficheskij adapter
3F0-3F7      kontroller NGMD
3F8-3FF      kommunikacionnyj adapter COM1 (modem PCjr)




   Tol'ko ochen' nemnogie IBM PC i PCjr ispol'zuyut kassetnyj  mag-
nitofon, a XT i AT ne podderzhivayut  ego voobshche.  Pomimo togo, chto
on ochen' nenadezhen, obmen s kassetnym magnitofonom vozmozhen tol'-
ko posledovatel'nyj, no ne s pryamym dostupom. Tem ne menee, mogut
byt' prichiny dlya programmirovaniya kassetnogo magnitofona na PCjr.
Imejte vvidu, chto kassetnye operacii ispol'zuyut kanal 2 mikroshe-
my  tajmera 8253 [2.1.1], poetomu ne pytajtes'  odnovremenno  is-
pol'zovat' etot kanal dlya  drugih  celej.  Otmetim takzhe, chto pri
operacii  chteniya  s kassety, zapreshcheno preryvanie vremeni  sutok,
poetomu schetchik vremeni sutok  BIOS  budet davat' nevernoe znache-
nie.

   Vysokij uroven'.

   Hotya  kassetnye fajly obrabatyvayutsya sovershenno po-drugomu chem
diskovye fajly, odnako komandy dostupa k nim sovershenno analogich-


ny. Na kassetu mogut zapisyvat'sya tol'ko programmnye fajly i pos-
ledovatel'nye fajly dannyh.  Poslednie mogut vklyuchat' fajly izob-
razheniya pamyati. Otmetim, chto dannye ne mogut dobavlyat'sya k posle-
dovatel'nym fajlam.  Pri sozdanii, imenam fajlov dayutsya sleduyushchie
odnobajtnye rasshireniya:

   .B      programma na Bejsike
   .P      zashchishchennaya programma na Bejsike
   .A      programma na Bejsike v formate ASCII
   .M      fajl izobrazheniya pamyati
   .D      posledovatel'nyj fajl dannyh

   Dlya sohraneniya fajla na kassete napishite SAVE "CAS1:imyafajla".
Dlya zagruzki programmy - LOAD "CAS1:imyafajla". V poslednem sluchae
lenta progonyaetsya do teh por,  poka  nuzhnyj fajl ne budet najden,
pri etom imya kazhdogo vstrechennogo fajla budet vyvodit'sya na ekran
(kassety ne ispol'zuyut katalogi).   Esli zaprosit' nesushchestvuyushchij
fajl, to budet vyveden polnyj spisok fajlov na kassete.

   Srednij uroven'.

   BIOS rabotaet s kassetnoj lentoj porciyami v 256-bajtnye bloki.
Naboru blokov predshestvuet "lider", kotoryj sostoit iz 256 bajtov
ASCII  1.  Lider zavershaetsya nulevym bitom sinhronizacii.   Zatem
sleduet bajt sinhronizacii so  znacheniem  16H, a zatem 256 bajtov
dannyh.  Posle etogo idut 2 bajta kontrolya oshibok, a zatem  novyj
blok dannyh, soprovozhdayushchijsya  paroj  bajt proverki oshibok i t.d.
Vsya  posledovatel'nost'  zavershaetsya  chetyrehbajtnym   "hvostom",
soderzhashchim kody ASCII 1.
   Dlya chteniya dannyh s kassety na  do ispol'zovat' funkciyu 2 pre-
ryvaniya 15H.  Net neobhodimosti otkryvat' fajl, kak eto  delaetsya
pri diskovyh operaciyah. ES:BX  ukazyvayut  na bufer v pamyati, kuda
budut  posylat'sya dannye, a CX - chislo bajtov, kotorye nado  schi-
tat'.  Pri vozvrate DX soobshchit  skol'ko bajtov prochitano na samom
dele, a ES:BX budut ukazyvat' na poslednij schitannyj bajt plyus 1.
Flag perenosa budet  raven  0,  esli  chtenie  proshlo uspeshno, a v
protivnom  sluchae AH budet soderzhat' 1, esli problema s kontrolem
oshibki, 2 - pri oshibke chteniya dannyh  i 3 - pri otsutstvii dannyh
na lente.
   Funkciya  3 preryvaniya 15H zapisyvaet dannye na kassetu.  ES:BX
ukazyvayut na pervyj  bajt  dannyh,  a  CX  soderzhit chislo bajtov,
kotoroe  nado  zapisat'.  Pri vozvrate ES:BX ukazyvayut  na  bajt,
sleduyushchij za poslednim zapisannym.  Motor upravlyaetsya funkciyami 0
(vklyuchenie) i 1 (vyklyuchenie) preryvaniya 15H. Dlya etih funkcij net
vyhodnyh registrov.




   Hotya ochen' nemnogie komp'yutery osnashcheny svetovym perom, tem ne
menee  eto  odno iz nemnogih vspomogatel'nyh  ustrojstv,  kotoroe
podderzhivaetsya kak  oborudovaniem,  tak  i operacionnoj sistemoj.
Svetovoe pero rabotaet s pomoshch'yu nebol'shogo opticheskogo detektora
na konchike pera.  Po hodu  skanirovaniya  ekrana elektronnym luchom
iniciiruetsya impul's opticheskogo detektora, kogda puchok dostigaet


tochki ekrana, nad  kotoroj  nahoditsya  pero.  Vremya vozniknoveniya
etogo impul'sa, otnositel'no signalov gorizontal'noj i vertikal'-
noj sinhronizacii, pozvolyaet opredelit' poziciyu svetovogo pera.

   Vysokij uroven'.

   Bejsik mozhet opredelyat'  poziciyu svetovogo pera dvumya sposoba-
mi.  Pri pervom programma nepreryvno opredelyaet status pera.  Pri
vtorom, kogda pero ispol'zuetsya, to upravlenie vremenno peredaet-
sya procedure, obespechivaemoj Vashej programmoj.  Dlya  nepreryvnogo
kontrolya za perom  nado  ispol'zovat'  operator PEN kak funkciyu v
forme  X = PEN(n), gde n - kodovyj nomer, opredelyayushchij kakuyu  in-
formaciyu Vy hotite poluchit' o pere i ego pozicii.  Vozmozhnye zna-
cheniya n takie:

  0    vozvrashchaet -1, esli pero bylo vyklyucheno so vremeni posled-
       nego zaprosa, 0 - esli net
  1    vozvrashchaet poslednyuyu koordinatu x (0-319 ili 0-639), v ko-
       toroj pero bylo  vklyucheno  (ono  moglo  byt'  vposledstvii
       peredvinuto, esli ostavalos' vklyuchennym)
  2    vozvrashchaet poslednyuyu koordinatu y (0-199), v kotoroj pero
       bylo  vklyucheno.
  3    vozvrashchaet -1, esli pero vklyucheno i 0 - esli net
  4    vozvrashchaet tekushchuyu x koordinatu (0-319 ili 0-639) pera
  5    vozvrashchaet tekushchuyu y koordinatu (0-199) pera
  6    vozvrashchaet poziciyu - nomer stroki (1-24), v kotoroj  pero
       bylo poslednij raz aktivizirovano
  7    vozvrashchaet poziciyu - nomer stolbca (1-40 ili 1-80), v ko-
       toroj pero bylo poslednij raz aktivizirovano
  8    vozvrashchaet tekushchuyu poziciyu - nomer stroki (1-24)
  9    vozvrashchaet tekushchuyu poziciyu - nomer stolbca (1-40 ili 1-80)

   V dannom primere  opredelyaetsya  vklyucheno  li  pero, i esli eto
tak, to beretsya tekushchee ego polozhenie:

100 IF NOT PEN(3) THEN 130   'proveryaem vklyucheno li pero
110 X = PEN(4)               'poluchaem koordinatu tochki po osi x
120 Y = PEN(5)               'poluchaem koordinatu tochki po osi y
130 ...                      'prodolzhaem programmu

   Bolee gibkie vozmozhnosti ispol'zovaniya svetovogo pera  predos-
tavlyayutsya operatorom ON PEN GOSUB.  |tot operator ukazyvaet nomer
stroki, v kotoroj nachinaetsya procedura, aktiviziruemaya pri  vklyu-
chenii pera. Bejsik dostigaet etogo proverkoj sostoyaniya pera posle
vypolneniya kazhdoj ego instrukcii.  Procedura mozhet poluchit' pozi-
ciyu pera i predprinyat' trebuemye dejstviya. Kogda procedura zakan-
chivaetsya,  to programma prodolzhaetsya s togo mesta, gde  ona  byla
pri vklyuchenii pera.
   ON PEN GOSUB ne rabotaet do teh por, poka ona ne aktivizirova-
na  operatorom PEN ON.  PEN OFF otmenyaet ee rabotu.  Smysl  etogo
sostoit v tom, chto  postoyannaya  proverka  statusa  pera zamedlyaet
rabotu  programmy, poetomu ee nado osushchestvlyat' tol'ko kogda  eto
neobhodimo.  Esli programma  nachinaet  vypolnyat' kritichekuyu chast'
koda, kogda nel'zya ispol'zovat' proceduru ON PEN GOSUB,  napishite


PEN STOP. V etom sluchae budet prodolzhat'sya proverka statusa pera,
i esli pero budet vklyucheno, to etot fakt budet zapomnen.   Odnako
poka ne budet vstrechen operator PEN ON, upravlenie ne budet pere-
davat'sya procedure ON PEN GOSUB.
   Dannyj primer vyzyvaet ostanovku programmy, kogda nazhata knop-
ka na svetovom pere. Tochka  v  pozicii  svetovogo pera vklyuchaetsya
proceduroj, obrabatyvayushchej vklyuchenie svetovogo pera.

100 ON PEN GOSUB 5000   'ustanavlivaem proceduru dlya svetovogo
110 PEN ON              'pera i vklyuchaem rezhim otslezhivaniya ego
 .
 .
5000 '''procedura obrabotki svetovogo pera
5010 X = PEN(4)         'poluchaem koordinatu X
5020 Y = PEN(5)         'poluchaem koordinatu Y
5030 PSET(X,Y)          'vklyuchit' etu tochku
5040 RETURN             '

   Srednij uroven'.

   Funkciya  4 preryvaniya 10H BIOS soobshchaet tekushchuyu poziciyu sveto-
vogo pera.  U nee net vhodnyh registrov. Pri vozvrate AX soderzhit
0,  esli pero ne vklyucheno i 1 - esli polucheny novye znacheniya  dlya
ego pozicii. Vozvrashchaetsya dva  nabora  koordinat, pozicii tochki i
pozicii stroki i stolbca. Pozicii simvola soderzhatsya v DX, prichem
DH soderzhit stroku (0-24), a DL  -  stolbec (0-79). Poziciya tochki
soderzhitsya  v CH i BX, prichem CH soderzhit vertikal'nuyu koordinatu
(0-199), a BX - gorizontal'nuyu (0-319 ili 0-639, v zavisimosti ot
rezhima terminala).

;---chitaem i zapominaem polozhenie svetovogo pera
   MOV  AH,4            ;nomer funkcii
   INT  10H             ;preryvanie BIOS
   CMP  AH,1            ;novaya poziciya?
   JE   NO_READING      ;esli net, to uhodim
   MOV  COL,BX          ;sohranyaem gorizontal'nuyu koordinatu
   MOV  CL,CH           ;pomeshchaem vertikal'nuyu koordinatu
   MOV  CH,0            ;v CX
   MOV  ROW,CX          ;sohranyaem vertikal'nuyu koordinatu

   Nizkij uroven'.

   Po svoej suti svetovoe pero yavlyaetsya rasshireniem  videosistemy
i kak takovoe ispol'zuet mikroshemu kontrollera CRT 6845. Poziciya
svetovogo  pera  daetsya odnim 2-hbajtnym znacheniem, hranyashchimsya  v
registrah 10H (starshij bajt) i  11H  (mladshij bajt) mikroshemy. V
[4.1.1]  ob®yasnyaetsya kak chitat' registry mikroshemy.   Posmotrite
primer.  Port s adresom  3DCH  ustanavlivaet  zadvizhku  svetovogo
pera, a s nomerom 3DBH - sbrasyvaet ee.

;---proverka svetovogo pera i chtenie ego pozicii
   MOV  DX,3DAH       ;ukazyvaem na registr statusa
   IN   AL,DX         ;poluchaem informaciyu
   TEST AL,4          ;proveryaem vyklyuchatel'


   JNZ  NOT_SET       ;na vyhod
   TEST AL,2          ;proveryaem trigger
   JZ   NOT_SET       ;na vyhod
   SUB  DX,7          ;ukazyvaem na registr adresa 6845
   MOV  AL,10H        ;zapros na starshij bajt pozicii pera
   OUT  DX,AL         ;posylaem zapros
   INC  DX            ;ukazyvaem na registr dannyh 6845
   IN   AL,DX         ;poluchaem znachenie
   XCNG AH,AL         ;zapominaem ego v AH
   DEC  DX            ;vozvrashchaemsya k adresnomu registru
   MOV  AL,11H        ;teper' hotim poluchit' mladshij bajt
   OUT  DX,AL         ;posylaem zapros
   INC  DX            ;nazad k registru dannyh
   IN   AL,DX         ;teper' eto znachenie v AX




   Igrovoj port mozhet podderzhivat' 2 dzhojstika ili 4 "vesla". Dlya
dzhojstika on soobshchaet dve  koordinaty  i  status dvuh knopok; dlya
vesla on soobshchaet odnu koordinatu i status odnoj knopki. Neskol'-
ko vspomogatel'nyh ustrojstv, takih  kak graficheskoe tablo, takzhe
mozhet byt' podklyucheno k igrovomu portu; ih rabota mozhet osushchestv-
lyat'sya parallel'no s rabotoj  dzhojstika.  Dannyj  razdel posvyashchen
chteniyu  koordinat, a v sleduyushchem obsuzhdaetsya kak poluchit'  status
knopok.

   Vysokij uroven'.

   Funkciya STICK vozvrashchaet pozicii  po osyam, ukazyvaemuyu sleduyu-
shchimi kodovymi nomerami:

   0    os' X dzhojstika A
   1    os' Y dzhojstika A
   2    os' X dzhojstika B
   3    os' Y dzhojstika B

Vam nuzhno napisat', naprimer, X = STICK(0) i v X budet soderzhat'-
sya znachenie koordinaty X dlya  dzhojstika  A.  No eta funkciya imeet
lovushku, o kotoroj Vam neobhodimo znat'. Tol'ko pri ispol'zovanii
koda  0  dejstvitel'no chitayutsya koordinaty  dzhojstika,  pri  etom
chitayutsya vse 4 znacheniya. Kodovye nomera 1-3 prosto soobshchayut poka-
zaniya, prochitannye kodom 0. CHtoby poluchit' poslednie 3 koordinaty
Vam neobhodimo pered etim ispol'zovat' funkciyu X = STICK(0), dazhe
esli Vam ne nuzhno znat' znachenie, vozvrashchaemoe kodom 0.
   Dzhojstiki  otlichayutsya  po  svoim  fizicheskim  harakteristikam,
poetomu neobhodimo nastraivat' ih,  chtoby ih predel'nye polozheniya
sovpadali  s granicami ekrana.  V sleduyushchem primere pokazano  kak
eto delaetsya. V  primere  nepreryvno  risuetsya  tochka, v pozicii,
ukazyvaemoj dzhojstikom, dejstvie, kotoroe trebuetsya, chtoby diapa-
zon znachenij,  prinimaemyh  igrovym  portom,  preobrazovyvalsya  v
diapazon pozicij ekrana.


100 '''poluchaem predel'nye pokazaniya dzhojstika
110 STRIG ON            'razreshaem knopki
120 V= STRIG(0)         'chistim starye pokazaniya
130 PRINT "Briefly push button 1 when stick is farthest to left"
140 XLEFT = STICK(0)    'poluchaem samoe levoe znachenie
150 IF STRIG(0) = 0 THEN 140  'zhdem nazhatiya knopki
160 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
170 PRINT "Briefly push button 1 when stick is farthest to right"
180 XRIGHT = STICK(0)   'poluchaem samoe pravoe znachenie
190 IF STRIG(0) = 0 THEN 180  'zhdem nazhatiya knopki
200 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
210 PRINT "Briefly push button 1 when stick is farthest to top"
220 V = STICK(0): YTOP = STICK(1)  'samoe verhnee znachenie
230 IF STRIG(0) = 0 THEN 220  'zhdem nazhatiya knopki
240 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
250 PRINT "Briefly push button 1 when stick farthest to bottom"
260 V = STICK(0): YBOTTOM = STICK(1)  'samoe nizhnee znachenie
270 IF STRIG(0) = 0 THEN 260  'zhdem nazhatiya knopki
280 STRIG OFF           'zakonchili
290 '''poluchaem mnozhiteli dlya ustanovki na razmer ekrana
300 XRIGHT = XRIGHT - XLEFT   'gorizontal'nyj razmer
310 XMULTIPLIER = 320/XRIGHT  'vychislyaem chislo tochek na delenie
320 YBOTTOM = YBOTTOM - YTOP  'vertikal'nyj razmer
330 YMULTIPLIER = 200/B/YBOTTOM  'chislo tochek na delenie
340 '''teper' vychislyaem koordinaty v rezhime umerennogo razresheniya
350 X = STICK(0)        'poluchaem gorizontal'nuyu poziciyu
360 Y = STICK(1)        'poluchaem vertikal'nuyu poziciyu
370 X = (X - XLEFT)*XMULTIPRIER  'privodim k ekranu
380 Y = (Y - YTOP)*YMULTIPRIER   '
390 PSET(X,Y)           'vyvodim tochku v nuzhnoj pozicii
400 GOTO 350            'povtoryaem

   Srednij uroven'.

   Tol'ko  AT predostavlyaet podderzhku dzhojstika na urovne  opera-
cionnoj sistemy.  |to funkciya 84H preryvaniya 15H, kotoraya vozvra-
shchaet koordinaty, prichem:

   AX  =  koordinata X dzhojstika A
   BX  =  koordinata Y dzhojstika A
   CX  =  koordinata X dzhojstika B
   DX  =  koordinata Y dzhojstika B

Pri vhode pomestite v DX 1. Kogda v DX soderzhitsya 0, to eta funk-
ciya vozvrashchaet sostoyanie knopok dzhojstika  [7.3.4].  Pri vozvrate
flag perenosa ustanovlen, kogda u mashiny net igrovogo porta.

   Nizkij uroven'.

   Informaciya  o  koordinatah oboih dzhojstikov ili  vseh  chetyreh
vesel hranitsya v odnom bajte,  dostup  k  kotoromu osushchestvlyaetsya
cherez port 201H. Vot znachenie ego bitov:


Bit             Dzhojstik                  Veslo

 3      koordinata Y dzhojstika B      koordinata vesla D
 2      koordinata X dzhojstika B      koordinata vesla C
 1      koordinata Y dzhojstika A      koordinata vesla B
 0      koordinata X dzhojstika A      koordinata vesla A

   Koordinata  mozhet  opisyvat'sya odnim bitom za  schet  izmereniya
vremennyh intervalov.  Poshlite v  port bajt s proizvol'nym znache-
niem.   |to privedet k tomu, chto mladshie 4 bita obnulyatsya.  Zatem
postoyanno schityvajte znachenie iz porta, zameryaya interval vremeni,
cherez kotoryj interesuyushchij Vas bit stanet ravnym 1. |tot interval
proporcionalen pozicii dzhojstika po interesuyushchej Vas osi.  Maksi-
mal'ny eintervaly sootvetstvuyut  nizhnej pozicii po osi Y i pravoj
pozicii po osi X.  Nezavisimo ot pozicii, bity menyayutsya ot 0 k  1
ochen' bystro, po sravneniyu s  mehanicheskoj  skorost'yu peremeshcheniya
dzhojstika ili vesla.  Poetomu programma mozhet s bol'shoj tochnost'yu
poluchit' snachala poziciyu koordinaty Y, a zatem poziciyu koordinaty
X.   Net neobhodimosti testirovat' kazhduyu koordinatu otdel'no.  V
dannom primere opredelyaetsya koordinata X dzhojstika A.

;---poluchaem koordinatu X dzhojstika A
   MOV  DX,201H         ;adres igrovogo porta
   OUT  DX,AL           ;posylaem v port proizvol'noe znachenie
   MOV  AH,1            ;proveryaem bit 1
   MOV  SI,0            ;inicializiruem schetchik
NEXT:   IN   AL,DX      ;chitaem znachenie iz porta
   TEST AL,AH           ;proveryaem bit 1
   JE   FINISHED        ;vyhod, kogda bit ustanovlen
   INC  SI              ;inache, uvelichivaem schetchik
   LOOP NEXT            ;na nachalo cikla
FINISHED:




   Igrovoj port podderzhivaet dva dzhojstika  ili chetyre "vesla", a
takzhe  ryad  graficheskih ustrojstv.  Pri etom  mozhet  opredelyat'sya
status do chetyreh knopok  ustrojstv.   Proverka  sostoyaniya knopok
mozhet  byt'  slozhnym delom, poskol'ku programma  mozhet  ne  imet'
vozmozhnosti postoyanno proveryat'  ih, a knopka mozhet byt' nazhata i
otpushchena, poka programma zanyata drugimi delami. Mozhet byt' sozda-
na special'naya procedura dlya resheniya etoj problemy. Status knopok
avtomaticheski  chitaetsya neskol'ko raz v sekundu, bez special'nogo
zaprosa na eto programmy; kogda  okazyvaetsya,  chto knopka nazhata,
to  upravdenie  peredaetsya  procedure, kotoraya  opredelyaet  kakaya
knopka nazhata i predprinimaet nuzhnye dejstviya.

   Vysokij uroven'.

   Bejsik ispol'zuet operator  STRIG  dlya  chteniya statusa knopok.
Operator STRIG dostatochno hitryj, chtoby obnaruzhit' nazhatie  knop-
ki, dazhe esli programma  v  dannyj  moment ne zanimaetsya statusom
knopki, t.e.  programma mozhet zaprosit': "Bylo li nazhatie knopki,
so vremeni moego poslednego zaprosa?"  |to svojstvo ochen' polezno


dlya videoigr, poskol'ku programma mozhet zanimat'sya  manipulyaciyami
s ekranom, ne  zabotyas'  o  postoyannoj  proverke  statusa knopok.
Odnako  eto sushchestvenno zamedlyaet skorost' vypolneniya  programmy,
poskol'ku proverka statusa knopok osushchestvlyaetsya posle vypolneniya
kazhdogo operatora.  Po etoj prichine, STRIG rabotaet tol'ko  kogda
on prednamerenno vklyuchen, a on  mozhet vklyuchat'sya i vyklyuchat'sya po
hodu programmy.
   STRIG rabotaet dvumya sposobami.  Vo-pervyh, on mozhet  rabotat'
kak  funkciya,  kotoraya  neposredstvenno  chitaet  tekushchie znacheniya
knopok, v forme X = STRIG(n). Zdes' n - kodovyj nomer:

   0    Knopka A1 nazhata so vremeni poslednego vyzova
   1    Knopka A1 v dannyj moment otpushchena
   2    Knopka B1 nazhata so vremeni poslednego vyzova
   3    Knopka B1 v dannyj moment otpushchena
   4    Knopka A2 nazhata so vremeni poslednego vyzova
   5    Knopka A2 v dannyj moment otpushchena
   6    Knopka B2 nazhata so vremeni poslednego vyzova
   7    Knopka B2 v dannyj moment otpushchena

Vo  vseh sluchayah funkciya vozvrashchaet -1, esli opisanie primenimo i
0 - esli net.
   Vtoroj sposob  ispol'zovaniya  STRIG  eto  forma,  v kotoroj on
avtomaticheski  pereklyuchaet na proceduru pri nazhatii knopki.  Nado
napisat' ON STRIG(n) GOSUB nomerstroki. Nomer stroki daet nachal'-
nyj  nomer stroki procedury.  CHislo n otnositsya k knopke, gde 0 =
A1, 2 = B1, 4 = A2 i 6 = B2.   Kazhdaya knopka mozhet obrabatyvat'sya
svoej proceduroj ili mozhet byt' odna procedura dlya vseh knopok.
   Dlya  aktivizacii  funkcii STRIG vklyuchite v programmu  operator
STRIG(n) ON.  V kachestve  znacheniya n ispol'zuyutsya chetyre perechis-
lennyh koda.  CHtoby otmenit' ego (uskoryaya rabotu programmy) napi-
shite STRIG(n) OFF.  Imeetsya takzhe  tret'ya vozmozhnost'.  STRING(n)
STOP privodit k tomu, chto nazhatie knopki zapominaetsya, no nikakih
dejstvij ne predprinimaetsya do ocherednogo operatora STRING(n) ON.
|to svojstvo predohranyaet ot nezhelatel'nyh pereryvov iz-za opera-
tora ON STRING GOSUB.   Tem  ne  menee,  pri  vypolnenii  usloviya
STRIG(n) STOP programma zamedlyaetsya.
   Sleduyushchij  primer pokazyvaet dejstvie ON STRIG GOSUB.   Primer
punkta [7.3.3] soderzhit stroki, pokazyvayushchie formu X = STRIG.

100 ON STRIG(0) GOSUB 5000   'perehod na 5000 pri nazhatii
 .                           'knopki A1
200 STRIG(0) ON    'vklyuchaem proverku nazhatiya knopki
 .
300 STRIG(0) STOP  'otmenyaem uhod na proceduru
 .
400 STRIG(0) ON    'vozobnovlyaem uhod na proceduru
 .
500 STRIG(0) OFF   'otmenyaem proverku nazhatiya knopki
 .
5000 '''zdes' nahoditsya procedura obrabotki nazhatiya knopki A1
 .
5500 RETURN        'vozvrat k tomu mestu, otkuda popali syuda


   Srednij uroven'.

   Tol'ko AT predostavlyaet  podderzhku  dzhojstika na urovne opera-
cionnoj sistemy.  Funkciya 84H preryvaniya 15H vozvrashchaet ustanovku
knopok v bitah 4-7 registra AL, kak  pokazano nizhe.  Pri vhode DX
dolzhen soderzhat' 0; kogda DX soderzhit 1, to vmesto etogo  vozvra-
shchayutsya koordinaty dzhojstika [7.3.3]. Pri vozvrate registr pereno-
sa ustanavlivaetsya, kogda mashina ne imeet igrovogo porta.

;---proveryaem knopku #2 dzhojstika B (bit 7)
   MOV  AH,84H          ;nomer funkcii
   MOV  DX,0            ;zapros sostoyaniya knopok
   INT  15H             ;vyzov funkcii
   JC   NO_JOYSTICK     ;esli net dzhojstika, to na vyhod
   TEST AL,10000000B    ;proveryaem bit 7
   JNZ  BUTTON_DOWN     ;perehod esli knopka nazhata

   Nizkij uroven'.

   Bity  7-4 porta s adresom 201H soderzhat status knopok, svyazan-
nyh s igrovym portom.  Znachenie  bitov  menyaetsya v zavisimosti ot
togo, prisoedineny li dzhojstiki ili vesla:

Bit          Dzhojstik                Veslo
 7    Knopka #2 dzhojstika B     Knopka vesla D
 6    Knopka #1 dzhojstika B     Knopka vesla C
 5    Knopka #2 dzhojstika A     Knopka vesla B
 4    Knopka #1 dzhojstika A     Knopka vesla A

Programme  nuzhno prosto prochitat' znachenie iz  porta i  proverit'
ustanovku sootvetstvuyushchih bitov:

   MOV  DX,201H         ;adres porta igrovogo adaptera
   IN   AL,DX           ;poluchaem znachenie iz nego
   TEST AL,0010B        ;proveryaem bit 1 (knopka A2 nazhata?)
   JNZ  BUTTON_A2       ;esli da, to na proceduru obrabotki

Programma imeet obychno bolee vazhnye dela, chem postoyanno proveryat'
igrovoj  port, odnako nastol'ko zhe byssmyslenno vremya ot  vremeni
proveryat' port, rassovyvaya  proceduru po raznym chastyam programmy.
CHtoby  poluchit' effekt otlova nazhatiya knopok, analogichnyj opisan-
nomu v Bejsike, Vam  pridetsya  sozdat'  dopolnenie  k  preryvaniyu
vremeni  sutok, kak opisano v [2.1.7].  Preryvanie obychno  vypol-
nyaetsya 18.2 raza v sekundu i kazhdyj raz Vy mozhete proveryat' igro-
voj port i predprinimat' nuzhnye dejstviya pri neobhodimosti.

Prilozheniya.

   Prilozhenie A.  Dvoichnye i shestnadcatirichnye chisla i  adresaciya
pamyati.

   Osnovnoj edinicej hraneniya dannyh v komp'yutere yavlyaetsya bit. V
bol'shinstve  mikrokomp'yuterov vosem' bitov ob®edineny v bajt, pri
etom kazhdyj bit bajta mozhet  byt'  ustanovlen ili "vklyuchen" (= 1)
ili  sbroshen ili "vyklyuchen" (= 0), dopuskaya 256 raznyh variantov.
Takim obrazom, v odnom bajte mozhno  predstavit' 256 raznyh simvo-
lov  (rasshirennyj nabor kodov ASCII) ili celoe chislo v  diapazone
ot 0 do 255.  Hotya my privykli  zapisyvat' eti chisla v desyatichnoj
forme,  oni mogut zapisyvat'sya takzhe v dvoichnoj ili  shestnadcati-
richnoj forme - ih znacheniya  pri  etom  ne izmenyayutsya, a programmy
mogut s odinakovoj legkost'yu chitat' eti znacheniya kak v toj, tak i
v drugoj forme. Vmesto  togo,  chtoby  govorit', chto v odnom bajte
mogut  hranit'sya chisla ot 0 do 255, mozhno skazat', chto mogut hra-
nit'sya dvoichnye chisla ot 00000000 do 11111111 ili shestnadcatirich-
nye  chisla ot 00 do FF.  Poskol'ku mozhno pereputat' raznye formy,
to dvoichnye  i  shestnadcatirichnye  chisla  otmechayutsya  special'nym
obrazom. V yazyke assemblera za dvoichnymi chislami sleduet bukva B,
a za shestnadcatirichnymi chislami  -  bukva  H, naprimer, 11111111B
ili  FFH.   Bejsik firmy Microsoft  predvaryaet  shestnadcatirichnye
chisla simvolami &H, naprimer  &FFH; k sozhaleniyu, on ne raspoznaet
chisla v dvoichnoj forme.

Dvoichnye chisla:

   Kogda  soderzhimoe  bajta predstavlyaetsya v dvoichnoj  forme,  to
trebuetsya 8 cifr. Kazhdaya cifra sootvetstvuet odnomu bitu, kotorye
numeruyutsya  ot 0 do 7.  Kak i v desyatichnyh chislah cifry  raspola-
gayutsya sprava nalevo, ot mladshih k starshim razryadam. V otlichii ot
desyatichnyh  chisel, v kotoryh kazhdaya posleduyushchaya cifra vesit v  10
raz bol'she svoej  sosedki  sprava,  dvoichnye  cifry  imeyut tol'ko
vdvoe  bol'shij  ves.  Takim obrazom, samaya pravaya  cifra  schitaet
edinicy, vtoraya - dvojki,  tret'ya  - chetverki i t.d., do znacheniya
128 dlya vos'moj cifry bajta.  |to oznachaet, chto esli pervaya cifra
ravna 1, to pribavlenie k nej 1  privodit  k tomu, chto ona stanet
0, a 1 budet perenesena vo vtoruyu cifru, kak dlya desyatichnyh chisel
9 + 1 = 0 i perenos edinicy  v  sleduyushchij  razryad.  Vot kak chisla
pervogo desyatka predstavlyayutsya v dvoichnoj forme:

   00000000               0
   00000001               1
   00000010               2
   00000011               3
   00000100               4
   00000101               5
   00000110               6
   00000111               7
   00001000               8
   00001001               9
   00001010              10

   V etoj posledovatel'nosti bol'shinstvo nulej sleva neobyazatel'-
ny, t.e. etu posledovatel'nost' mozhno zapisat' i v vide 0, 1, 10,


11, 100, 101 i t.d.  Nuli vklyucheny tol'ko dlya togo, chtoby  napom-
nit' Vam, chto bajt sostavlyaetsya vosem'yu ciframi, sootvetstvuyushchimi
bitam.  V to vremya kak nabor nulej i edinic mozhet byt'  neskol'ko
utomitel'nym, Vy mozhete legche  rabotat' s dvoichnymi chislami, esli
budete predstavlyat' ih sebe sleduyushchim obrazom:

   bit     7     6     5     4     3     2     1     0
znachenie  128   64    32    16     8     4     2     1

Kogda  Vy vstrechaete dvoichnoe chislo 10000001, to ustanovleny bity
7 i 0.  Bit 7 sootvetstvuet 128,  a bit 0 - 1, poetomu desyatichnoe
znachenie bajta ravno 129.  Esli etot bajt predstavlyaet simvol, to
on sootvetstvuet kodu ASCII  129,  kotoryj predstavlyaet bukvu u s
umlyautom (v al'ternativnoj kodirovke GOSTa - bukvu B).  Naoborot,
chtoby opredelit' cepochku bitov  dlya  bukvy A, kotoraya ravna ASCII

Prilozhenie B. Bitovye operacii v Bejsike.

   V Bejsike nel'zya ispol'zovat' chisla v dvoichnoj forme. On rass-
matrivaet cepochku bitov 11000000  kak 11 millionov, a ne kak 192.
Odnako  manipulyacii s cepochkami bitov chasto neobhodimy pri  prog-
rammirovanii,  poskol'ku  trebuetsya  chitat' i izmenyat' soderzhimoe
statusnyh bajtov i statusnyh registrov.
   V  bol'shinstve sluchaev k cepochkam bitov primenyayutsya dve  logi-
cheskie  operacii.  |to operacii ILI (OR) i I (AND) i obe oni dos-
tupny v Bejdiapazone
ot 0 do 255.  Hotya my privykli  zapisyvat' eti chisla v desyatichnoj
forme,  oni mogut zapisyvat'sya takzhe v dvoichnoj ili  shestnadcati-
richnoj forme - ih znacheniya  pri  etom  ne izmenyayutsya, a programmy
mogut s odinakovoj legkost'yu chitat' eti znacheniya kak v toj, tak i
v drugoj forme. Vmesto  togo,  chtoby  govorit', chto v odnom bajte
mogut  hranit'sya chisla ot 0 do 255, mozhno skazat', chto mogut hra-
nit'sya dvoichnye chisla ot 00000000 do 11111111 ili shestnadcatirich-
nye  chisla ot 00 do FF.  Poskol'ku mozhno pereputat' raznye formy,
to dvoichnye  i  shestnadcatirichnye  chisla  otmechayutsya  special'nym
obrazom. V yazyke assemblera za dvoichnymi chislami sleduet bukva B,
a za shestnadcatirichnymi chislami  -  bukva  H, naprimer, 11111111B
ili  FFH.   Bejsik firmy Microsoft  predvaryaet  shestnadcatirichnye
chisla simvolami &H, naprimer  &FFH; k sozhaleniyu, on ne raspoznaet
chisla v dvoichnoj forme.

Dvoichnye chisla:

   Kogda  soderzhimoe  bajta predstavlyaetsya v dvoichnoj  forme,  to
trebuetsya 8 cifr. Kazhdaya cifra sootvetstvuet odnomu bitu, kotorye
numeruyutsya  ot 0 do 7.  Kak i v desyatichnyh chislah cifry  raspola-
gayutsya sprava nalevo, ot mladshih k starshim razryadam. V otlichii ot
desyatichnyh  chisel, v kotoryh kazhdaya posleduyushchaya cifra vesit v  10
raz bol'she svoej  sosedki  sprava,  dvoichnye  cifry  imeyut tol'ko
vdvoe  bol'shij  ves.  Takim obrazom, samaya pravaya  cifra  schitaet
edinicy, vtoraya - dvojki,  tret'ya  - chetverki i t.d., do znacheniya
128 dlya vos'moj cifry bajta.  |to oznachaet, chto esli pervaya cifra
ravna 1, to pribavlenie k nej 1  privodit  k tomu, chto ona stanet
0, a 1 budet perenesena vo vtoruyu cifru, kak dlya desyatichnyh chisel
9 + 1 = 0 i perenos edinicy  v  sleduyushchij  razryad.  Vot kak chisla
pervogo desyatka predstavlyayutsya v dvoichnoj forme:

   00000000               0
   00000001               1
   00000010               2
   00000011               3
   00000100               4
   00000101               5
   00000110               6
   00000111               7
   00001000               8
   00001001               9
   00001010              10


   V etoj posledovatel'nosti bol'shinstvo nulej sleva neobyazatel'-
ny, t.e. etu posledovatel'nost' mozhno zapisat' i v vide 0, 1, 10,
11, 100, 101 i t.d.  Nuli vklyucheny tol'ko dlya togo, chtoby  napom-
nit' Vam, chto bajt sostavlyaetsya vosem'yu ciframi, sootvetstvuyushchimi
bitam.  V to vremya kak nabor nulej i edinic mozhet byt'  neskol'ko
utomitel'nym, Vy mozhete legche  rabotat' s dvoichnymi chislami, esli
budete predstavlyat' ih sebe sleduyushchim obrazom:

   bit     7     6     5     4     3     2     1     0
znachenie  128   64    32    16     8     4     2     1

Kogda  Vy vstrechaete dvoichnoe chislo 10000001, to ustanovleny bity
7 i 0.  Bit 7 sootvetstvuet 128,  a bit 0 - 1, poetomu desyatichnoe
znachenie bajta ravno 129.  Esli etot bajt predstavlyaet simvol, to
on sootvetstvuet kodu ASCII  129,  kotoryj predstavlyaet bukvu u s
umlyautom (v al'ternativnoj kodirovke GOSTa - bukvu B).  Naoborot,
chtoby opredelit' cepochku bitov  dlya  bukvy A, kotoraya ravna ASCII
 bloki.
Naboru blokov predshestvuet "lider", kotoryj sostoit iz 256 bajtov
ASCII  1.  Lider zavershaetsya nulevym bitom sinhronizacii.   Zatem
sleduet bajt sinhronizacii so  znacheniem  16H, a zatem 256 bajtov
dannyh.  Posle etogo idut 2 bajta kontrolya oshibok, a zatem  novyj
blok dannyh, soprovozhdayushchijsya  paroj  bajt proverki oshibok i t.d.
Vsya  posledovatel'nost'  zavershaetsya  chetyrehbajtnym   "hvostom",
soderzhashchim kody ASCII 1.
   Dlya chteniya dannyh s kassety na  do ispol'zovat' funkciyu 2 pre-
ryvaniya 15H.  Net neobhodimosti otkryvat' fajl, kak eto  delaetsya
pri diskovyh operaciyah. ES:BX  ukazyvayut  na bufer v pamyati, kuda
budut  posylat'sya dannye, a CX - chislo bajtov, kotorye nado  schi-
tat'.  Pri vozvrate DX soobshchit  skol'ko bajtov prochitano na samom
dele, a ES:BX budut ukazyvat' na poslednij schitannyj bajt plyus 1.
Flag perenosa budet  raven  0,  esli  chtenie  proshlo uspeshno, a v
protivnom  sluchae AH budet soderzhat' 1, esli problema s kontrolem
oshibki, 2 - pri oshibke chteniya dannyh  i 3 - pri otsutstvii dannyh
na lente.

   Funkciya  3 preryvaniya 15H zapisyvaet dannye na kassetu.  ES:BX
ukazyvayut na pervyj  bajt  dannyh,  a  CX  soderzhit chislo bajtov,
kotoroe  nado  zapisat'.  Pri vozvrate ES:BX ukazyvayut  na  bajt,
sleduyushchij za poslednim zapisannym.  Motor upravlyaetsya funkciyami 0
(vklyuchenie) i 1 (vyklyuchenie) preryvaniya 15H. Dlya etih funkcij net
vyhodnyh registrov.




   Hotya ochen' nemnogie komp'yutery osnashcheny svetovym perom, tem ne
menee  eto  odno iz nemnogih vspomogatel'nyh  ustrojstv,  kotoroe
podderzhivaetsya kak  oborudovaniem,  tak  i operacionnoj sistemoj.
Svetovoe pero rabotaet s pomoshch'yu nebol'shogo opticheskogo detektora
na konchike pera.  Po hodu  skanirovaniya  ekrana elektronnym luchom
iniciiruetsya impul's opticheskogo detektora, kogda puchok dostigaet
tochki ekrana, nad  kotoroj  nahoditsya  pero.  Vremya vozniknoveniya
etogo impul'sa, otnositel'no signalov gorizontal'noj i vertikal'-
noj sinhronizacii, pozvolyaet opredelit' poziciyu svetovogo pera.


   Vysokij uroven'.

   Bejsik mozhet opredelyat'  poziciyu svetovogo pera dvumya sposoba-
mi.  Pri pervom programma nepreryvno opredelyaet status pera.  Pri
vtorom, kogda pero ispol'zuetsya, to upravlenie vremenno peredaet-
sya procedure, obespechivaemoj Vashej programmoj.  Dlya  nepreryvnogo
kontrolya za perom  nado  ispol'zovat'  operator PEN kak funkciyu v
forme  X = PEN(n), gde n - kodovyj nomer, opredelyayushchij kakuyu  in-
formaciyu Vy hotite poluchit' o pere i ego pozicii.  Vozmozhnye zna-
cheniya n takie:

  0    vozvrashchaet -1, esli pero bylo vyklyucheno so vremeni posled-
       nego zaprosa, 0 - esli net
  1    vozvrashchaet poslednyuyu koordinatu x (0-319 ili 0-639), v ko-
       toroj pero bylo  vklyucheno  (ono  moglo  byt'  vposledstvii
       peredvinuto, esli ostavalos' vklyuchennym)
  2    vozvrashchaet poslednyuyu koordinatu y (0-199), v kotoroj pero
       bylo  vklyucheno.
  3    vozvrashchaet -1, esli pero vklyucheno i 0 - esli net
  4    vozvrashchaet tekushchuyu x koordinatu (0-319 ili 0-639) pera
  5    vozvrashchaet tekushchuyu y koordinatu (0-199) pera
  6    vozvrashchaet poziciyu - nomer stroki (1-24), v kotoroj  pero
       bylo poslednij raz aktivizirovano
  7    vozvrashchaet poziciyu - nomer stolbca (1-40 ili 1-80), v ko-
       toroj pero bylo poslednij raz aktivizirovano
  8    vozvrashchaet tekushchuyu poziciyu - nomer stroki (1-24)
  9    vozvrashchaet tekushchuyu poziciyu - nomer stolbca (1-40 ili 1-80)

   V dannom primere  opredelyaetsya  vklyucheno  li  pero, i esli eto
tak, to beretsya tekushchee ego polozhenie:

100 IF NOT PEN(3) THEN 130   'proveryaem vklyucheno li pero
110 X = PEN(4)               'poluchaem koordinatu tochki po osi x
120 Y = PEN(5)               'poluchaem koordinatu tochki po osi y
130 ...                      'prodolzhaem programmu

   Bolee gibkie vozmozhnosti ispol'zovaniya svetovogo pera  predos-
tavlyayutsya operatorom ON PEN GOSUB.  |tot operator ukazyvaet nomer
stroki, v kotoroj nachinaetsya procedura, aktiviziruemaya pri  vklyu-
chenii pera. Bejsik dostigaet etogo proverkoj sostoyaniya pera posle
vypolneniya kazhdoj ego instrukcii.  Procedura mozhet poluchit' pozi-
ciyu pera i predprinyat' trebuemye dejstviya. Kogda procedura zakan-
chivaetsya,  to programma prodolzhaetsya s togo mesta, gde  ona  byla
pri vklyuchenii pera.

   ON PEN GOSUB ne rabotaet do teh por, poka ona ne aktivizirova-
na  operatorom PEN ON.  PEN OFF otmenyaet ee rabotu.  Smysl  etogo
sostoit v tom, chto  postoyannaya  proverka  statusa  pera zamedlyaet
rabotu  programmy, poetomu ee nado osushchestvlyat' tol'ko kogda  eto
neobhodimo.  Esli programma  nachinaet  vypolnyat' kritichekuyu chast'
koda, kogda nel'zya ispol'zovat' proceduru ON PEN GOSUB,  napishite
PEN STOP. V etom sluchae budet prodolzhat'sya proverka statusa pera,
i esli pero budet vklyucheno, to etot fakt budet zapomnen.   Odnako
poka ne budet vstrechen operator PEN ON, upravlenie ne budet pere-


davat'sya procedure ON PEN GOSUB.
   Dannyj primer vyzyvaet ostanovku programmy, kogda nazhata knop-
ka na svetovom pere. Tochka  v  pozicii  svetovogo pera vklyuchaetsya
proceduroj, obrabatyvayushchej vklyuchenie
   ERROR        ;na obrabotku oshibki
   INC  BX                 ;uvelichivaem ukazatel'
   LOOP NEXT_CHAR          ;vyvodim sleduyushchij simvol

   Standartnoe  preryvanie MS DOS dlya vyvoda na printer eto funk-
ciya 5 preryvaniya 21H.  Prosto  pomestite  simvol v DL i vypolnite
preryvanie.  |ta funkciya vsegda vyvodit na LPT1 i u nee net vozv-
rashchaemyh registrov.

;---vyvod dannyh na LPT1
   MOV  AH,5       ;nomer funkcii
   MOV  DL,CHAR    ;gotovim pechataemyj simvol
   INT  21H        ;posylaem ego na pr
                   ;N,1)*2^(N-1)
2040 NEXT
2050 RETURN

Prilozhenie V. Osnovnye svedeniya ob yazyke assemblera.

   CHitatel'  etoj  knigi, ne znakomyj s yazykom assemblera,  skoro
pojmet, chto mnogie programmistskie tryuki ne mogut byt' dostignuty
drugimi  sredstvami.  Hotya izuchenie yazyka assemblera trebuet  ot-
del'noj knigi, v  etom  prilozhenii  privodyatsya  osnovnye ponyatiya,
kotorye  pomogut novichkam razobrat'sya v primerah na  etom  yazyke.
Vnimatel'nyj prosmotr  razdelov,  posvyashchennyh  srednemu i nizkomu
urovnyam,  dast Vam vozmozhnost' poluchit' predstavlenie o tom,  kak
rabotaet assembler, posle chego namnogo legche izuchit' raznye chast-
nye  voprosy.  Zdes' obsuzhdayutsya ne vse assemblernye  instrukcii,
vstrechayushchiesya v programmah,  no  Vy  obnaruzhite,  chto  okolo 95 %
instrukcij, vstrechennyh Vami v programmah, opisany zdes', a  zna-
chenie ostal'nyh mozhet byt'  ponyato blagodarya kommentariyam k prog-
rammam.
   Mikroprocessor 8088 imeet 13 16-razryadnyh registrov, kazhdyj iz
kotoryh imeet svoi  funkcii.  V  to  vremya  kak v yazykah vysokogo
urovnya  Vy mozhete pomestit' dva chisla v peremennye, a zatem  slo-
zhit' eti peremennye, to v yazyke assemblera eti chisla pomeshchayutsya v
registry mikroprocessora, a zatem skladyvayutsya znacheniya, soderzha-
shchiesya v  registrah.  Vse  operacii  v  yazyke assemblera sostoyat v
obmene  dannyh  s registrami, a zatem vypolnenii operacij na  re-
gistrah, takih kak izmenenie otdel'nyh  bitov, vypolnenie arifme-
ticheskih  operacij i t.d.  Odnoj iz prichin vysokoj  effektivnosti
yazyka assemblera yavlyaetsya  hranenie  dannyh v registrah mikropro-
cessora;  kompilyatory imeyut tendenciyu vozvrashchat' vse  znacheniya  v
pamyat' posle vypolneniya operacii, a dostup k pamyati trebuet bol'-
shogo vremeni.  Na ris. V-1 pokazany 13 registrov mikroprocessorov
8088 i 80286 (poslednij imeet dopolnitel'nye  sredstva dlya mnogo-
zadachnoj raboty, kotorye my ne budem rassmatrivat' zdes').
   Registry  AX, BX, CX i DX yavlyayutsya registrami obshchego  naznache-
niya.  Ih osobennost' sostoit v  tom,  chto operacii mogut proizvo-
dit'sya  ne tol'ko nad soderzhimym vsego registra, no  takzhe i  nad
polovinoj. Kazhdyj iz chetyreh registrov delitsya na starshuyu i mlad-
shuyu  chasti, naprimer, AH oboznachaet starshuyu polovinu registra AX,
a AL - mladshuyu.  Tochno tak zhe  assemblernaya programma mozhet imet'
dostup  k BH, BL, CH, CL, DH i DL.  |to svojstvo  ochen'  polezno,
poskol'ku chasto programme  prihoditsya rabotat' s bajtnymi velichi-
nami.   Registry  BP, SI i DI takzhe dostatochno udobny,  hotya  oni
mogut prinimat' tol'ko  16-bitnye  znacheniya.  Kazhdyj bit registra
flagov soobshchaet o sootvetstvuyushchem statuse processora, naprimer, o
tom, chto pri vypolnenii  arifmeticheskoj  operacii  byl perenos za
razryadnuyu setku.
   V obshchem sluchae znacheniya pomeshchayutsya v registry s pomoshch'yu  inst-
rukcii MOV. MOV  AX,BX  peresylaet  soderzhimoe  registra BX v AX,
zatiraya  ranee soderzhashcheesya v AX znachenie.  MOV AH,BL privodit  k
peresylke bajta iz registra v  registr, no MOV AX,BL - nedopusti-
maya  instrukciya, tak kak znacheniya dolzhny imet' odinakovyj razmer.
Instrukciya MOV mozhet' takzhe peredavat' znacheniya iz pamyati, napri-
mer,  MOV  AX,ACCT_NUMBER.  Zdes' ACCT_NUMBER -  imya  peremennoj,
kotoruyu sozdal programmist,  sovsem  kak v yazyke vysokogo urovnya.
Peremennaya sozdaetsya operatorom vida ACCT_NUMBER DW 0.  |tot ope-
rator ostavlyaet  mesto  dlya  slova  (dvuh  bajtov), prisvaivaya im
znachenie 0.  Drugie dopustimye simvoly v etom operatore eto DD  -
dlya dvojnogo slova i DB - dlya bajta  ili strok.  Assembler sledit


za adresami peremennyh, poetomu pri assemblirovanii operatora MOV
AX,ACCT_NUMBER imya peremennoj zamenyaetsya na ee adres.
   Rabota s imenami peremennyh - samyj prostoj sposob identifika-
cii dannyh v programmah na yazyke assemblera. No imeyutsya razlichnye
sposoby hitroj  adresacii,  kotorye  pozvolyayut  programme hranit'
massivy  ili ispol'zovat' ukazateli.  Naprimer,  MOV  AX,[BX][SI]
posylaet v AX znachenie, kotoroe  soderzhitsya  po smeshcheniyu, ravnomu
summe  znachenij registrov BX i SI.  No ot chego otschityvat' smeshche-
nie? Otvet zaklyuchaetsya v tom, chto vse dannye sobrany v odnu chast'
programmy,  a ves' ispolnyaemyj kod - v druguyu.  CHast', otvedennaya
pod dannye, nazyvaetsya segmentom dannyh,  a pod programmu - kodo-
vym  segmentom.  Vse peremennye, otvedennye dlya hraneniya  dannyh,
adresuyutsya cherez smeshchenie otnositel'no nachala segmenta dannyh.
   Poziciya v pamyati, s kotoroj nachinaetsya segment dannyh, hranit-
sya v registre DS, odnom iz  chetyreh  segmentnyh  registrov. Kak i
vse  ostal'nye registry mikroprocessora on 16-razryadnyj,  poetomu
on ne mozhet soderzhat' chisla, bol'shie  chem 65535. Kakim zhe obrazom
segment  danyh mozhet ukazyvat' na yachejki pamyati, raspolozhennye  v
verhnej chasti megabajtnogo adresnogo  prostranstva? Otvet sostoit
v tom, chto segmentnye registry avtomaticheski umnozhayutsya na 16,  a
rezul'tat ukazyvaet na  mesto  v  pamyati,  s  kotorogo nachinaetsya
segment.  Takim obrazom, segmenty vsegda vyravneny na  16-bajtnuyu
granicu. Posle togo kak segment ustanovlen, vse ostal'nye regist-
ry  mogut  soderzhat' smeshcheniya, ukazyvayushchie na lyuboj iz  sleduyushchih
65535 bajtov. Registr dopolnitel'nogo segmenta (ES) takzhe ispol'-
zuetsya dlya ukazaniya na dannye, hranyashchiesya v pamyati.
   Sredi  assemblernyh instrukcij, kotorye Vy chasto budete vstre-
chat' v etoj knige, est' instrukcii  zagruzki segmentnyh i otnosi-
tel'nyh adresov peremennyh.  MOV AX,SEG ACCT_NUMBER pomeshchaet zna-
chenie segmentnogo registra,  v  kotorom  raspolozhen ACCT_NUMBER v
AX, a vposledstvii eto znachenie budet pereslano v DS. MOV BX,OFF-
SET ACCT_NUMBER pomeshchaet v BX  smeshchenie  peremennoj ACCT_NUMBER v
segmente dannyh.  Posle vypolneniya etih operacij DS:BX budut uka-
zyvat' na ACCT_NUMBER. Esli  ACCT_NUMBER yavlyaetsya odnomernym mas-
sivom,  to  dlya  ukazaniya na opredelennyj element  massiva  mozhet
ispol'zovat'sya  dobavochnoe  smeshchenie.  Vy  chasto budete vstrechat'
takzhe  instrukciyu  LEA,  predostavlyayushchuyu drugoj  sposob  zagruzki
smeshcheniya.
   Kodovyj segment soderzhit  posledovatel'nost' mashinnyh instruk-
cij, sostavlyayushchih programmu.  Naprimer, instrukciya MOV sushchestvuet
v vide neskol'kih bajtov mashinnogo koda, znachenie bajtov kotorogo
opredelyaet  v kakoj registr idet peresylka i otkuda.  Registr  IP
(schetchik komand) soderzhit velichinu smeshcheniya, kotoraya ukazyvaet na
tu  instrukciyu  v kodovom segmente, kotoraya sejchas dolzhna  vypol-
nyat'sya.  Posle vypolneniya instrukcii IP uvelichivaetsya takim obra-
zom,  chtoby  on ukazyval na sleduyushchuyu instrukciyu.   V  prostejshej
programme schetchik komand  budet  peredvigat'sya  ot  pervogo bajta
kodovogo segmenta k poslednemu, gde programma i zavershitsya.   No,
kak i drugie programmy,  programma na yazyke assemblera mozhet byt'
razbita na procedury (podprogrammy), poetomu schetchik komand mozhet
prygat' iz odnogo mesta kodovogo segmenta v drugoe.
   Kogda schetchik komand prygaet v drugoe mesto kodovogo segmenta,
to  ego staroe znachenie dolzhno byt' zapomneno, s tem chtoby  mozhno
bylo vernut'sya v nuzhnoe mesto, tak kak eto delaet operator RETURN


v  Bejsike, vozvrashchaya upravlenie v to mesto, otkuda byla  vyzvana
procedura. V yazyke assemblera  procedure prisvaivaetsya imya, napr-
imer,  COMBINE_DATA, i operator CALL COMBINE_DATA peredaet uprav-
lenie v proceduru.  Procedura  zavershaetsya instrukciej RET (vozv-
rat).  Pri vyzove procedury processor zapominaet tekushchee znachenie
schetchika komand, zatalkivaya ego na stek.
   Stek eto oblast', ispol'zuemaya dlya vremennogo hraneniya dannyh.
Posle zaversheniya procedury staroe znachenie schetchika komand beret-
sya iz steka i vypolnenie  programmy  prodolzhaetsya. Stek takzhe so-
derzhitsya  v  otdel'nom segmente, kotoryj, sovershenno estestvenno,
nazyvaetsya segmentom steka. Emu  sootvetstvuet segmentnyj registr
SS. V registre SP hranitsya ukazatel' steka, kotoryj vsegda ukazy-
vaet na vershinu steka i  izmenyaetsya pri zasylke na stek i vyborke
iz steka.
   Na  pervyj  vzglyad stek kazhetsya dostatochno neuklyuzhim  sposobom
hraneniya informacii, no u nego est'  dva preimushchestva. Vo-pervyh,
dostup k ego soderzhimomu namnogo bystree, chem k peremennym,  hra-
nyashchimsya v pamyati,  a,  vo-vtoryh,  stek  mozhet ispol'zovat'sya dlya
mnogih  celej.   On mozhet hranit' adresa vozvrata  iz  procedury,
vlozhennoj v druguyu  proceduru.  Vposledstvii,  to zhe samoe prost-
ranstvo  mozhet ispol'zovat'sya programmistom dlya hraneniya  dannyh,
kotorye dolzhny sejchas  obrabatyvat'sya,  no dlya kotoryh ne hvataet
mesta v registrah mikroprocessora. Programma vytalkivaet soderzhi-
moe registra na stek komandoj PUSH, a pozdnee zabiraet ego ottuda
komandoj POP.  V assemblernyh programmah, privedennyh v etoj kni-
ge, Vy ne raz vstretites' s  instrukciyami  tipa PUSH BX i POP DX.
Nepravil'nyj  poryadok  obmena dannymi so stekom -  luchshij  sposob
privesti assemblernuyu programmu k krahu.
   Posle togo kak programmist na  assemblere  ustanovil  tri seg-
mentnyh registra (CS, DS i SS) i zagruzil dannye v registry  mik-
roprocessora on imeet shirokij  nabor vstroennyh sredstv, kotorymi
processor mozhet pomoch' programmistu na assemblere.  Vot  naibolee
rasprostranennye iz nih:

ADD AX,BX   Pribavlyaet BX k AX. Sushchestvuet takzhe instrukciya vychi-
            taniya (SUB), a takzhe varianty obeih etih instrukcij.

MUL BL      Umnozhaet BL na AX.  Imeetsya takzhe instrukciya  deleniya
            (DIV), a takzhe varianty obeih etih instrukcij.

INC BL      Uvelichivaet BL na 1.  Imeetsya takzhe instrukciya umen'-
            sheniya (DEC).

LOOP XXX    Vozvrashchaet  programmu nazad k stroke pomechennoj  XXX,
            povtoryaya process stol'ko  raz, kakoe chislo soderzhitsya
            v CX (analogichno instrukcii FOR ..  TO .. NEXT v Bej-
            sike).

OR AL,BL    Vypolnyaet  operaciyu  logicheskogo  ILI  nad soderzhimym
            registrov  AL i BL, prichem rezul'tat pomeshchaetsya v AL.
            Imeyutsya takzhe instrukcii AND, XOR i NOT.


SHL AX,1    Sdvigaet vse bity, soderzhashchiesya v AX, na odnu poziciyu
            vlevo.   |to ekvivalentno umnozheniyu soderzhimogo AX na
            2.  Drugie instrukcii  sdvigayut  bity vpravo ili osu-
            shchestvlyayut ciklicheskij sdvig. Vse eti instrukcii ochen'
            polezny dlya  bitovyh  operacij,  takih  kak ustanovka
            tochek ekrana.
IN AL,DX    Pomeshchaet v AX bajt, obnaruzhennyj v porte, adres koto-
            rogo ukazan v DX. Imeetsya takzhe instrukciya OUT.

JMP         Peredaet upravlenie  v  drugoe  mesto  programmy, kak
            instrukciya GOTO v Bejsike.  JMP YYY peredaet upravle-
            nie na stroku programmy, imeyushchuyu metku YYY.

CMP AL,BL   Sravnivaet soderzhimoe  AL  i  BL.  Za instrukciej CMP
            obychno sleduet instrukciya uslovnogo perehoda.  Napri-
            mer, esli za instrukciej CMP  sleduet instrukciya JGE,
            to perehod proizojdet tol'ko esli BL bol'she ili ravno
            AL.  Instrukciya CMP dostigaet togo zhe rezul'tata, chto
            i  instrukciya  IF ..  THEN v Bejsike (na  samom  dele
            instrukciya IF ..   THEN  perevoditsya  interpretatorom
            Bejsika v instrukciyu CMP).

TEST AL,BL  Proveryaet  est'  li sredi bitov, ustanovlennyh v  BL,
            takie,  kotorye  ustanovleny  takzhe  i  v AL. Za etoj
            instrukciej obychno sleduet komanda uslovnogo  pereho-
            da, tak zhe kak za CMP. TEST ochen' polezen pri prover-
            ke  statusnyh  bitov (bitovye operacii  ochen'  prosto
            realizuyutsya v yazyke assemblera).

MOVS        Peresylaet stroku, dlina  kotoroj  soderzhitsya v CX, s
            mesta, na kotoroe ukazyvaet SI, na mesto, na  kotoroe
            ukazyvaet DI. Imeetsya eshche  neskol'ko  drugih instruk-
            cij, svyazannyh s peresylkoj i poiskom strok.

YAzyk assemblera obespechivaet neskol'ko variantov etih instrukcij,
a  takzhe ryad drugih special'nyh instrukcij.  Imeetsya takzhe  celyj
klass instrukcij, nazyvaemyh psevdooperatorami, kotorye pomeshchayut-
sya v tekst programmy s cel'yu ukazaniya assembleru kak obrabatyvat'
dannuyu programmu. Naprimer, odin  iz tipov psevdooperatorov avto-
maticheski  vstavlyaet chasto ispol'zuemyj kusok koda po vsej  prog-
ramme. Takaya porciya koda nazyvaetsya makrosom i imenno eto svojst-
vo assemblera dalo emu nazvanie "makroassembler".
   I,  nakonec,  assembler  imeet vozmozhnost',  kotoroj  zaviduyut
(ili, po krajnej mere, dolzhny  zavidovat')  vse kto programmiruet
tol'ko na yazykah vysokogo urovnya. Imeetsya vvidu vozmozhnost' opti-
mal'nym obrazom  ispol'zovat'  preryvaniya  operacionnoj  sistemy.
Ved'  eto nichto inoe, kak gotovye procedury.  Odnako vmesto togo,
chtoby vyzyvat' ih po CALL, oni vyzyvayutsya instrukciej INT. INT21H
vyzyvaet  preryvanie s shestnadcatirichnym nomerom 21.  Imeetsya ryad
takih preryvanij, kak v bazovoj sisteme vvoda/vyvoda PZU, tak i v
operacionnoj sisteme, prichem nekotorye iz etih procedur neobychaj-
no moshchny.  Na samom dele nekotorye iz nih nastol'ko tesno svyazany
s  sistemoj,  chto Vy prakticheski ne mozhete sami napisat'  ekviva-
lentnuyu proceduru.  YAzyki  vysokogo urovnya pozvolyayut ispol'zovat'


mnogie iz etih preryvanij. Oni ispol'zuyut ih dlya vyvoda na ekran,
priema vvoda s klaviatury i dostupa k diskam.  No mnogie dejstvi-
tel'no poleznye preryvaniya ignoriruyutsya yazykami vysokogo  urovnya,
naprimer takie,  kotorye  pozvolyayut  zapustit' iz odnoj programmy
druguyu.   Nekotorye  translyatory (takie kak Lattice C  ili  Turbo
Pascal) pozvolyayut dostup k etim  preryvaniyam,  esli Vy znaete kak
ih gotovit' i Vy mozhete ispol'zovat' razdely srednego urovnya etoj
knigi dlya etoj celi.
   Pered  vyzovom  preryvaniya  nekotoraya  informaciya  dolzhna byt'
pomeshchena v registry processora.  Naprimer, preryvanie, verikal'no
sdvigayushchee ekran, dolzhno znat'  razmery  sdvigaemogo  okna, chislo
strok  na  kotoroe ego nado sdvinut' i t.d.  |ti  znacheniya  chasto
nazyvayut vhodnymi registrami.  Snova  i snova Vy budete vstrechat'
slova "pri vhode BX dolzhen soderzhat' ...", opisyvayushchie specifika-
ciyu vhodnyh  registrov.   Analogichno,  pri vozvrate iz preryvaniya
nekotorye  registry vozvrashchayut znacheniya ili statusnuyu informaciyu.
Oni nazyvayutsya  vyhodnymi  registrami  i  my opisyvaem ih slovami
"pri vyhode AX soderzhit ...".  Zachastuyu odno preryvanie  soderzhit
mnogo funkcij. V chastnosti, operacionnaya sistema vpihnula prakti-
cheski vse svoi vozmozhnosti v preryvanie 21H.  Poetomu pri  vyzove
preryvaniya neobhodimo  ukazyvat'  nomer  funkcii.  Vse preryvaniya
(kak  BIOS  tak i DOS) peredayut nomer funkcii v AH  (inogda v  AL
soderzhitsya nomer podfunkcii).
   Vse skazannoe  v  osnovnom  sluzhit  tol'ko  chtoby  dat' pervoe
predstavlenie o predmete.  No esli Vy budete vnimatel'no prosmat-
rivat' prostejshie primery, soderzhashchiesya  v etoj knige, to Vy poj-
mete  stoyashchuyu  za nimi logiku.  YAzyk assemblera  imeet  reputaciyu
trudnogo yazyka. No to, chto  Vy  tol'ko  chto prochitali - nastoyashchaya
chepuha. Imeetsya dostatochno slozhnostej i v yazykah vysokogo urovnya.
I esli oshibki v assemblernoj  programme byvaet ochen' slozhno obna-
ruzhit',  to v osnovnom eto svyazano s tem, chto sam tekst programmy
namnogo dlinnee, chem ekvivalentnyj  tekst na yazyke vysokogo urov-
nya  (odnako assemblernyj kod namnogo plotnee).  V nastoyashchee vremya
mnogie professionaly pishut  programmy  na yazyke C, zatem analizi-
ruyut  effektivnost' i perepisyvayut kriticheskie kusochki programmy,
kotorye rashoduyut mnogo  vremeni,  na yazyke assemblera. Nevozmozh-
nost'  napisaniya takih assemblernyh procedur mozhet inogda  svesti
usiliya programmista k  nulyu.  Poetomu  najdite horoshij bukvar' po
assembleru i pristupajte! Vozmozhno samoj bol'shoj nagradoj dlya Vas
stanet moment, kogda Vy  nakonec  dejstvitel'no  stanete ponimat'
kak zhe rabotaet komp'yuter.

Prilozhenie G.  Vklyuchenie assemblernyh procedur v programmy  na
                  Bejsike.

   Procedury na yazyke assemblera sostoyat iz strok bajtov mashinno-
go koda. Pri vypolnenii etoj procedury Bejsik peredaet upravlenie
iz  posledovatel'nosti instrukcij, sostavlyayushchih programmu na Bej-
sike, v to mesto, gde  hranyatsya  instrukcii,  kotorye  mogut byt'
dekodirovany  v  posledovatel'nost' instrukcij yazyka  assemblera.
Pri zavershenii assemblernoj  procedury  upravlenie vozvrashchaetsya v
to mesto bejsikovskoj programmy, otkuda byla vyzvana procedura.
   V etoj knige assemblernye procedury, ispol'zuemye v programmah
na Bejsike, privedeny v dvuh vidah. V oboih vidah procedury vklyu-
cheny  v programmu, a ne hranyatsya v vide otdel'nogo diskovogo faj-
la. Pri pervom sposobe trebuetsya, chtoby kody procedury nahodilis'
v  otdel'nom meste v pamyati, a pri vtorom, menee prinyatom,  etogo
ne trebuetsya.
   V pervom sposobe procedura pomeshchaetsya v operatory DATA i prog-
ramma  peresylaetsya v neispol'zuemuyu chast' pamyati, a zatem  vyzy-
vaetsya operatorom CALL. Nado pozabotit'sya o tom, chtoby kod proce-
dury  ne  nakladyvalsya na kakie-libo dannye i naoborot.   Obychnoe
reshenie etoj problemy sostoit v  tom,  chto procedura pomeshchaetsya v
te  adresa  pamyati,  k kotorym Bejsik ne mozhet  poluchit'  dostup.
Poskol'ku interpretator Bejsika ne  mozhet imet' dostup za predely
64K,  to  dlya sistemy, skazhem, s pamyat'yu  256K,  nuzhno  pomestit'
proceduru v starshie  64K.  Dlya  sistem  s  pamyat'yu 128K Vy dolzhny
vychislit'  skol'ko pamyati trebuetsya operacionnoj sisteme, Bejsiku
i drajveram  ustrojstv.   Dopustimo,  chtoby oni zanimali 25K plyus
64K,  ispol'zuemyh  Bejsikom.  V sistemah s 64K  ispol'zujte  pri
starte komandu CLEAR, kotoraya ogranichivaet ob®em pamyati dostupnyj
dlya Bejsika. CLEAR,n ogranichivaet Bejsik n bajtami.  Zatem pomes-
tite proceduru v samye verhnie adresa pamyati.
   Dlya ukazaniya nachala  oblasti,  kuda  budet pomeshchena procedura,
ispol'zujte  operator  DEF SEG, a zatem s pomoshch'yu operatora  READ
schityvayutsya bajty procedury  i  pomeshchayutsya  v  pamyat' do teh por,
poka vsya procedura ne budet pomeshchena na mesto. Naprimer:

100 DATA &Hxx, &Hxx, &Hxx, &Hxx, &Hxx  '10-bajtnaya procedura
110 DATA &Hxx, &Hxx, &Hxx, &Hxx, &Hxx
 .
 .
300 '''pomeshchaem proceduru v pamyat'
310 DEF SEG = &H3000   'ukazyvaem na oblast' pamyati
320 FOR N = 0 TO 9     'dlya kazhdogo iz 10 bajtov
330 READ Q             'chitaem bajt dannyh
340 POKE N,Q           'pomeshchaem ego v pamyat'
350 NEXT

   Posle  togo  kak procedura zagruzhena v pamyat' i Vy  hotite  ee
ispol'zovat', neobhodimo chtoby  poslednij operator DEF SEG ukazy-
val na nachalo procedury.  Zatem prisvojte celoj peremennoj znache-
nie 0 i napishite operator  CALL  s  imenem  etoj peremennoj. Esli
procedure  peredayutsya  parametry,  to oni dolzhny byt'  ukazany  v
skobkah v konce operatora CALL. Naprimer:


500 DEF SEG = &H3000   'ukazyvaem na nachalo procedury
510 DOGS = 12          'u nee 3 parametra
520 CATS = 44          '
530 POSSUMS = 1        '
540 CASUALTIES = 0     'nachinaem vypolnenie s 1-go bajta
550 CALL CASUALTIES(DOGS,CATS,POSSUMS)  'vypolnyaem proceduru

   Imeetsya  namnogo  bolee prostoj i ekonomichnyj sposob  sozdaniya
assemblernyh procedur, kotoryj  izbegaet  problemy  raspredeleniya
pamyati. Nado prosto sozdat' proceduru v vide strokovoj peremennoj
vnutri programmy.  Kazhdyj bajt  mozhet  byt' zakodirovan s pomoshch'yu
CHR$.  Zatem ispol'zujte funkciyu VARPTR dlya opredeleniya polozheniya
etoj stroki v pamyati. Smeshchenie po kotoromu nahoditsya eta peremen-
naya  hranitsya v dvuh bajtah, kotorye idut za tem, na kotoryj uka-
zhet VARPTR (v pervom bajte  soderzhitsya  dlina stroki). Zatem etot
adres ispol'zuetsya dlya vyzova procedury.  Otmetim sposob, kotorym
ispol'zuetsya operator DEF  SEG,  dlya  ukazaniya  na segment dannyh
Bejsika, s tem chtoby poluchennoe smeshchenie ukazyvalo na adres stro-
ki dlya operatora CALL. Naprimer:

100 DEF SEG         'ustanavlivaem segment na dannye Bejsika
110 X$ = "CHR$(B4)+..."  'kod procedury
120 Y = VARPTR(X$)       'poluchaem deskriptor stroki
130 Z = PEEK(Y+1)+PEEK(Y+2)*256  'vychislyaem ee adres
140 CALL Z

Mnogie znacheniya, vyrazhaemye  cherez CHR$() mogut byt' predstavleny
i v vide simvolov ASCII.  Vy mozhete pisat' ROUT = CHR$(12) + "AB"
vmesto ROUT = CHR$(12) + CHR$(65) + CHR$(66). Na samom dele bol'-
shinstvo simvolov ASCII mogut vvodit'sya putem nazhatiya klavishi Alt,
nabore nomera koda na dopolnitel'noj klaviature, a zatem otpuska-
niya  klavishi  Alt.  Odnako kody ot 0 do 31 ne mogut byt'  vvedeny
takim obrazom dlya nashih celej.

   Prilozhenie D. Ispol'zovanie drajvera ustrojstva ANSI.SYS.

   ANSI.SYS eto nebol'shaya programma, vhodyashchaya v sostav operacion-
noj  sistemy, kotoraya mozhet byt' zagruzhena v pamyat', s tem  chtoby
uvelichit' vozmozhnosti MS DOS. Ona ne sdelana chast'yu COMMAND.COM s
cel'yu ekonomiya pamyati, kogda ona ne ispol'zuetsya.  Sredstva, pre-
dostavlyaemye ANSI.SYS, mogut byt' ispol'zovany dlya udobstva prog-
rammirovaniya,  no  oni mogut takzhe sluzhit'  sredstvom  dostizheniya
nekotoroj  programmnoj  sovmestimosti  s ne IBM-ovskimi mashinami,
ispol'zuyushchimi MS DOS. |tot drajver ne predostavlyaet nikakih doba-
vochnyh vozmozhnostej, kotoryh nel'zya bylo by dobit'sya drugim obra-
zom,  no on delaet nekotorye vozmozhnosti upravleniya klaviaturoj i
terminalom namnogo bolee prostymi  (i obychno bolee medlenno). Vse
svojstva drajvera ANSI.SYS opisany v etoj knige pod sootvetstvuyu-
shchim zagolovkom.
   ANSI.SYS mozhet byt' zagruzhen  tol'ko  vo vremya zagruzki opera-
cionnoj sistemy. Nachinaya s  versii 2.0 sistema avtomaticheski ishchet
fajl CONFIG.SYS, tak zhe kak i fajl AUTOEXEC.BAT.  Fajl CONFIG.SYS
soderzhit razlichnye parametry, takie kak chislo sozdavaemyh buferov
dlya fajlov. No on soderzhit takzhe i imena teh drajverov ustrojstv,


kotorye dolzhny byt' zagruzheny i vklyucheny  v COMMAND.COM. ANSI.SYS
kak  raz i yavlyaetsya takim drajverom.  Nado prosto vklyuchit' v etot
fajl stroku DEVICE = ANSI.SYS.  Ona mozhet byt' edinstvennoj stro-
koj v fajle.  Dlya sozdaniya etogo fajla mozhno vospol'zovat'sya  ko-
mandoj COPY. Nado prosto vvesti s terminala takie stroki:

COPY CON: CONFIG.SYS <CR>
DEVICE = ANSI.SYS <CR>
<F6>  <CR>

Nazhatie  klavishi F6 zapisyvaet simvol Ctrl-Z (ASCII 26), otmechayu-
shchij konec fajla.

Prilozhenie E. Nabor instrukcij mikroprocessora 8088.

   CHislo taktov, kotoroe nado dobavit' dlya vychisleniya effektivno-
go adresa sleduyushchee:

     komponenty adresa          operandy                  takty

(a)  baza ili indeks            [BX],[BP],[DI],[SI]          5
(b)  smeshchenie                   metka ili smeshchenie           6
(v)  baza + indeks              [BX][SI], [BX][DI]           7
                                [BP][SI], [BP][DI]           8
(g)  smeshchenie + baza ili indeks [BX],[BP],[DI],[SI] + smeshch.  9
(d)  smeshchenie + baza + indeks   [BX][SI],[BX][DI] + smeshch.   11
                                [BP][SI],[BP][DI] + smeshch.   12

Neobhodimo dobavit' takzhe 2 takta  pri peresechenii segmenta.  Vot
vremena instrukcij:

        instrukciya                                takty   bajty

AAA                                                 4        1
AAD                                                60        2
AAM                                                83        1
AAS                                                 4        1
ADC  registr, registr                               3        2
ADC  registr, pamyat'                           9(13) + EA   2-4
ADC  pamyat', registr                          16(24) + EA   2-4
ADC  registr, znachenie                              4       3-4
ADC  pamyat', znachenie                         17(25) + EA   3-6
ADC  akkumulyator, znachenie                          4       2-3
ADD  registr, registr                               3        2
ADD  registr, pamyat'                           9(13) + EA   2-4
ADD  pamyat', registr                          16(24) + EA   2-4
ADD  registr, znachenie                              4       3-4
ADD  pamyat', znachenie                         17(25) + EA   3-6
ADD  akkumulyator, znachenie                          4       2-3
AND  registr, registr                               3        2
AND  registr, pamyat'                           9(13) + EA   2-4
AND  pamyat', registr                          16(24) + EA   2-4
AND  registr, znachenie                              4       3-4
AND  pamyat', znachenie                         17(25) + EA   3-6
AND  akkumulyator, znachenie                          4       2-3
CALL blizkaya procedura                             23        3
CALL dalekaya procedura                             36        5
CALL slovnyj ukazatel' v pamyati                  29 + EA    2-4
CALL slovnyj registr ukazatel'                     24        2
CALL dvuhslovnyj ukazatel' v pamyati              57 + EA    2-4
CBW                                                 2        1
CLC                                                 2        1
CLD                                                 2        1
CLI                                                 2        1
CMC                                                 2        1
CMP  registr, registr                               3        2
CMP  registr, pamyat'                           9(13) + EA   2-4
CMP  pamyat', registr                           9(13) + EA   2-4


CMP  registr, znachenie                              4       3-4
CMP  pamyat', znachenie                         10(14) + EA   3-6
CMP  akkumulyator, znachenie                          4       2-3
CMPS priemnik, istochnik                           22(30)     1

CMPS (REP) priemnik, istochnik              9 + 22(30)/povtor 1
CWD                                                 5        1
DAA                                                 4        1
DAS                                                 4        1
DEC  slovnyj registr                                2        1
DEC  bajtnyj registr                                3        2
DEC  pamyat'                                    15(23) + EA  2-4
DIV  bajtnyj registr                              80-90      2
DIV  slovnyj registr                            144-162      2
DIV  bajt pamyati                              (86-96) + EA  2-4
DIV  slovo pamyati                           (154-172) + EA  2-4
ESC  znachenie, pamyat'                           8(12) + EA  2-4
ESC  znachenie, registr                              2        2
HLT                                                 2        1
IDIV bajtnyj registr                            101-112      2
IDIV slovnyj registr                            165-185      2
IDIV bajt pamyati                            (107-118) + EA  2-4
IDIV slovo pamyati                           (175-194) + EA  2-4
IMUL bajtnyj registr                              80-98      2
IMUL slovnyj registr                            128-154      2
IMUL bajt pamyati                             (86-104) + EA  2-4
IMUL slovo pamyati                           (138-164) + EA  2-4
IN   akkumulyator, bajt znacheniya                   10(14)     2
IN   akkumulyator, DX                               8(12)     1
INC  slovnyj registr                                2        1
INC  bajtnyj registr                                3        2
INC  pamyat'                                    15(23) + EA  2-4
INT  3                                             52        1
INT  znachenie bajta, otlichnoe ot 3                 51        2
INTO                                           53 ili 4      1
IRET                                               32        1
JCXZ korotkaya metka                            18 ili 6      2
JMP  korotkaya metka                                15        2
JMP  blizkaya metka                                 15        3
JMP  dalekaya metka                                 15        5
Jxxx korotkaya metka                            16 ili 4      2
LAHF                                                4        1
LDS  slovnyj registr, dvojnoe slovo pamyati       24 + EA    2-4
LEA  slovnyj registr, slovo pamyati                2 + EA    2-4
LES  slovnyj registr, dvojnoe slovo pamyati       24 + EA    2-4
LOCK                                                2        1
LODS stroka-istochnik                             12(16)      1
LODS (REP) stroka-istochnik                 9+13(17)/povtor   1
LOOP    korotkaya metka                          17 ili 5     2
LOOPE   korotkaya metka                          18 ili 6     2
LOOPNE  korotkaya metka                          19 ili 5     2
LOOPNZ  korotkaya metka                          19 ili 5     2
LOOPZ   korotkaya metka                          18 ili 6     2
MOV  pamyat', akkumulyator                         10(14)      3


MOV  akkumulyator, pamyat'                         10(14)      3
MOV  registr, registr                               2        2
MOV  registr, pamyat'                           8(12) + EA   2-4
MOV  pamyat', registr                           9(13) + EA   2-4
MOV  registr, znachenie                              4       2-3
MOV  znachenie, registr                        10(14) + EA    3

MOV  segmentnyj registr, slovnyj registr            2        2
MOV  segmentnyj registr, slovo pamyati          8(12) + EA   2-4
MOV  slovnyj registr, segmentnyj registr            2        2
MOV  slovo pamyati, segmentnyj registr          9(13) + EA   2-4
MOVS priemnik, istochnik                          18(26)      1
MOVS (REP) priemnik, istochnik              9+17(25)/povtor   1
MUL  bajtnyj registr                              70-77      2
MUL  slovnyj registr                            118-133      2
MUL  bajt pamyati                              (76-83) + EA  2-4
MUL  slovo pamyati                           (128-143) + EA  2-4
NEG  registr                                        3        2
NEG  pamyat'                                    16(24) + EA  2-4
NOP                                                 3        1
NOT  registr                                        3        2
NOT  pamyat'                                    16(24) + EA  2-4
OR   registr, registr                               3        2
OR   registr, pamyat'                           9(13) + EA   2-4
OR   pamyat', registr                          16(24) + EA   2-4
OR   registr, znachenie                              4       3-4
OR   pamyat', znachenie                         17(25) + EA   3-6
OR   akkumulyator, znachenie                          4       2-3
OUT  bajt znacheniya, akkumulyator                   10(14)     2
OUT  DX, akkumulyator                               8(12)     1
POP  registr                                       12        1
POP  segmentnyj registr                            12        1
POP  pamyat'                                      25 + EA    2-4
POPF                                               12        1
PUSH registr                                       15        1
PUSH segmentnyj registr                            14        1
PUSH pamyat'                                      24 + EA    2-4
PUSHF                                              14        1
RCL  registr, 1                                     2        2
RCL  registr, CL                                 8+4/bit     2
RCL  pamyat', 1                                  15(23) + EA  2
RCL  pamyat', 1                               20(28)+EA+4/bit 2
RCR  registr, 1                                     2        2
RCR  registr, CL                                 8+4/bit     2
RCR  pamyat', 1                                  15(23) + EA  2
RCR  pamyat', 1                               20(28)+EA+4/bit 2
REP                                                 2        1
REPE                                                2        1
REPNE                                               2        1
REPZ                                                2        1
REPNZ                                               2        1
RET  (vnutrisegmentnyj, bez POP)                   20        1
RET  (vnutrisegmentnyj, s POP)                     24        3


RET  (mezhsegmentnyj, bez POP)                      32        1
RET  (mezhsegmentnyj, s POP)                        31        3
ROL  registr, 1                                     2        2
ROL  registr, CL                                 8+4/bit     2
ROL  pamyat', 1                                  15(23) + EA  2
ROL  pamyat', 1                               20(28)+EA+4/bit 2
ROR  registr, 1                                     2        2
ROR  registr, CL                                 8+4/bit     2
ROR  pamyat', 1                                  15(23) + EA  2
ROR  pamyat', 1                               20(28)+EA+4/bit 2
SAHF                                                4        1

SAL  registr, 1                                     2        2
SAL  registr, CL                                 8+4/bit     2
SAL  pamyat', 1                                  15(23) + EA  2
SAL  pamyat', 1                               20(28)+EA+4/bit 2
SAR  registr, 1                                     2        2
SAR  registr, CL                                 8+4/bit     2
SAR  pamyat', 1                                  15(23) + EA  2
SAR  pamyat', 1                               20(28)+EA+4/bit 2
SBB  registr, registr                               3        2
SBB  registr, pamyat'                           9(13) + EA   2-4
SBB  pamyat', registr                          16(24) + EA   2-4
SBB  registr, znachenie                              4       3-4
SBB  pamyat', znachenie                         17(25) + EA   3-6
SBB  akkumulyator, znachenie                          4       2-3
SCAS priemnik                                     15(19)     1
SCAS (REP) priemnik                          9+15(19)/povtor 1
SHL  registr, 1                                     2        2
SHL  registr, CL                                 8+4/bit     2
SHL  pamyat', 1                                  15(23) + EA  2
SHL  pamyat', 1                               20(28)+EA+4/bit 2
SHR  registr, 1                                     2        2
SHR  registr, CL                                 8+4/bit     2
SHR  pamyat', 1                                  15(23) + EA  2
SHR  pamyat', 1                               20(28)+EA+4/bit 2
STC                                                 2        1
STD                                                 2        1
STI                                                 2        1
STOS priemnik                                     11(15)     1
STOS (REP) priemnik                          9+10(14)/povtor 1
SUB  registr, registr                               3        2
SUB  registr, pamyat'                           9(13) + EA   2-4
SUB  pamyat', registr                          16(24) + EA   2-4
SUB  registr, znachenie                              4       3-4
SUB  pamyat', znachenie                         17(25) + EA   3-6
SUB  AL, znachenie                                   4       2-3
TEST registr, registr                               3        2
TEST registr, pamyat'                           9(13) + EA   2-4
TEST registr, znachenie                              5       3-4
TEST pamyat', znachenie                             11 + EA   3-6
TEST AL, znachenie                                   4       2-3
WAIT                                             3 + 5n      1
XCNG AL, slovnyj registr                            3        1


XCNG pamyat', registr                           17(25) + EA  2-4
XCNG registr, registr                               4        2
XLAT tablica-istochnik                              11        1
XOR  registr, registr                               3        2
XOR  registr, pamyat'                           9(13) + EA   2-4
XOR  pamyat', registr                          16(24) + EA   2-4
XOR  registr, znachenie                              4       3-4
XOR  pamyat', znachenie                         17(25) + EA   3-6
XOR  AL, znachenie                                   4       2-3

Prilozhenie ZH. Nabor instrukcij mikroprocessora 80286.

   Priderzhivayas' shemy, prinyatoj v dannoj knige, zdes' perechisle-
ny instrukcii tol'ko dlya rezhimov real'noj adresacii. Bolee moshchnyj
mikroprocessor 80286 ne trebuet dobavochnogo vremeni na vychislenie
effektivnyh  adresov,  net takzhe otlichiya v vypolnenii komand  nad
bajtnymi i  slovnymi  peremennymi.  Zvezdochka  ukazyvaet,  chto Vy
dolzhny  dobavit' odin takt, esli pri vychislenii  smeshcheniya  summi-
ruyutsya tri elementa. Bukva  m  ukazyvaet  chislo  bajtov sleduyushchej
instrukcii, a n - chislo povtorenij.

                                                  takty   bajty

AAA                                                 3       1
AAD                                                14       2
AAM                                                16       2
AAS                                                 3       1
ADC  registr/pamyat' s registrom                   2,7*      2
ADC  znachenie s registrom/pamyat'yu                 3,7*     3-4
ADC  znachenie s akkumulyatorom                       3      2-3
ADD  registr/pamyat' s registrom                   2,7*      2
ADD  znachenie s registrom/pamyat'yu                 3,7*     3-4
ADD  znachenie s akkumulyatorom                       3      2-3
AND  registr/pamyat' s registrom                   2,7*      2
AND  znachenie s registrom/pamyat'yu                 3,7*     3-4
AND  znachenie s akkumulyatorom                       3      2-3
CALL pryamoj vnutri segmenta                        7+m      3
CALL kosvennyj cherez registr/pamyat' vnutri seg-ta 7+m,11+m* 2
CALL pryamoj mezhdu segmenta                        13+m      5
CBW                                                 2       1
CLC                                                 2       1
CLD                                                 2       1
CLI                                                 3       1
CMC                                                 2       1
CMP  registr/pamyat' s registrom                   2,6*      2
CMP  registr s registrom/pamyat'yu                  2,7*      2
CMP  znachenie s registrom/pamyat'yu                 3,6*     3-4
CMP  znachenie s akkumulyatorom                       3      2-3
CMPS povtorennyj CX raz                          5 + 9n     2
CMPS bajt ili slovo                                 8       1
CWD                                                 2       1
DAA                                                 3       1
DAS                                                 3       1
DEC  registr/pamyat'                               2,7*      2
DEC  registr                                        2       1
DIV  bajtnyj registr                               14       2
DIV  slovnyj registr                               22       2
DIV  bajt pamyati                                   17*      2
DIV  slovo pamyati                                  25*      2
ESC                                              9-20*      2
HLT                                                 2       1
IDIV bajtnyj registr                               17       2
IDIV slovnyj registr                               25       2
IDIV bajt pamyati                                   20*      2
IDIV slovo pamyati                                  28*      2


IMUL bajtnyj registr                               13       2
IMUL slovnyj registr                               21       2
IMUL bajt pamyati                                   16*      2

IMUL slovo pamyati                                  24*      2
IMUL umnozhenie na celoe znachenie                21,24*     3-4
IN   fiksirovannyj port                             5       2
IN   peremennyj port                                5       1
INC  registr/pamyat'                               2,7*      2
INC  registr                                        2       1
INS  stroka                                      5 + 4m     2
INS  bajt ili slovo                                 5       1
INT  ukazannyj tip                               23 + m     2
INT  tip 3                                       23 + m     1
INTO                                           24 + m ili 3 1
IRET                                             17 + m     1
JCXZ                                           8 + m ili 4  2
JMP  korotkij/dlinnyj                             7 + m     2
JMP  pryamoj vnutri segmenta                       7 + m     2
JMP  kosvennyj cherez registr/pamyat'         7 + m,11 + m*   2
JMP  pryamoj mezhdu segmentami                      7 + m     2
Jxxx                                          7 + m ili 3   2
LAHF                                                2       1
LDS                                                 7*      2
LEA                                                 3*      2
LES                                                 7*      2
LOCK                                                0       1
LODS                                                5       1
LODS povtorennyj CX raz                         5 + 4n      1
LOOP                                           8 + 4n ili 4 2
LOOPZ/LOOPE                                    8 + 4n ili 4 2
LOOPNZ/LOOPNE                                  8 + 4n ili 4 2
MOV  registr v registr/pamyat'                      2,3*     2
MOV  registr/pamyat' v registr                      2,5*     2
MOV  znachenie v registr/pamyat'                     2,3*    3-4
MOV  znachenie v registr                             2      2-3
MOV  pamyat' v akkumulyator                           5       3
MOV  akkumulyator v pamyat'                           3       3
MOV  registr/pamyat' v segmentnyj registr           2,5*     2
MOV  segmentnyj registr v registr/pamyat'           2,3*     2
MOVS bajt ili slovo                                 5       1
MOVS povtorennoe CX raz                           5 + 4n    2
MUL  bajtnyj registr                               13       2
MUL  slovnyj registr                               21       2
MUL  bajt pamyati                                   16*      2
MUL  slovo pamyati                                  24*      2
NEG                                                 2       2
NOT  registr/pamyat'                               2,7*      2
OR   registr/pamyat' s registrom                   2,7*      2
OR   znachenie s registrom/pamyat'yu                 3,7*     3-4
OR   znachenie s akkumulyatorom                       3      2-3
OUT  fiksirovannyj port                             3       2
OUT  peremennyj port                                3       1
OUTS stroka                                      5 + 4m     2


OUTS bajt ili slovo                                 5       1
POP  pamyat'                                         5*      2
POP  registr                                        5       1
POP  segmentnyj registr                             5       1
POPA                                               19       1
POPF                                                5       1

PUSH pamyat'                                         5*      2
PUSH registr                                        3       1
PUSH segmentnyj registr                             3       1
PUSH znachenie                                       3      2-3
PUSHA                                              17       1
PUSHF                                               3       1
RCA  registr/pamyat' na 1                          2,7*      2
RCA  registr/pamyat' na CX                      5+n, 8+n*    2
RCA  registr/pamyat' na chislo                   5+n, 8+n*    3
RCR  registr/pamyat' na 1                          2,7*      2
RCR  registr/pamyat' na CX                      5+n, 8+n*    2
RCR  registr/pamyat' na chislo                   5+n, 8+n*    3
RET  vnutri segmenta                             11 + m     1
RET  vnutri segmenta, dobavlyaya znachenie k SP