gie 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 5.4.2 CHtenie/zapis' opredelennyh sektorov. 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]. 5.4.3 Zapis' v posledovatel'nye fajly. 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 ; 5.4.4 CHtenie iz posledovatel'nyh fajlov. 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