MODUL IQNDSK; GLOBAL RDSEC,WRSEC,CRTBUF,FREBUF, ACTDSK,ACTTRK,ACTSEC,ACTDMA; CONST FREE=255; (* volny buffer *) SECSZ=128; (* delka sektoru *) TYPE TSECTOR=ARRAY[1..128] OF BYTE; TTRKBUF=ARRAY[1..13] OF TSECTOR; TPBUF=^TBUF; TBUF=RECORD NXTBUF:TPBUF; DSK,TRK:BYTE; TRKBUF:TTRKBUF; END; TPTRKBUF=^TTRKBUF; VAR BUFHD,P,Q:TPBUF; ACTDSK,ACTTRK,ACTSEC:BYTE; ACTDMA:WORD; procedure MOVE(P, Q : word; L : integer); external; (* READ *) function PBIORS:byte; external; (* WRITE *) function PBIOWS:byte; external; (* SETTRK*) procedure PBIOST(TRK : byte); external; (* SETSEC*) procedure PBIOSS(SEC : byte); external; (* SETDMA*) procedure PBIOSA(ADR : word); external; (* SECTRN*) function PBIOTR(SEC : byte; TBLADR : word):integer; external; FUNCTION MODTRK:BYTE; (* Vypocte modifikovane cislo stopy *) BEGIN MODTRK:=ACTTRK*2+ORD(ODD(ACTSEC)) END; FUNCTION MODSEC:BYTE; (* Vypocte modifikovanee cislo sektoru *) BEGIN MODSEC:=(ACTSEC+1)DIV 2 END; PROCEDURE FREBUF; (* Oznaci vsechny buffery jako volne *) BEGIN P:=BUFHD; REPEAT P^.DSK:=FREE; P:=P^.NXTBUF UNTIL P=NIL; END; DYNAMIC PROCEDURE CRTBUF; (* Alokuje maximalni pocet bufferu *) VAR C:CHAR; BEGIN BUFHD:=NIL; REPEAT P:=BUFHD; NEW(BUFHD); BUFHD^.NXTBUF:=P; UNTIL (REF(C)-(BUFHD TYPE INTEGER+SIZE(TBUF))) < (NIL+SIZE(TBUF)+256); FREBUF; END; FUNCTION WRSEC:BYTE; (* Zapis sektoru na disketu a pripadne do bufferu *) LABEL 9; BEGIN P:=BUFHD; REPEAT IF (P^.DSK=ACTDSK) AND (P^.TRK=MODTRK) THEN BEGIN MOVE(REF(P^.TRKBUF[MODSEC]),ACTDMA,SECSZ); GOTO 9 END; P:=P^.NXTBUF; UNTIL P=NIL; 9: PBIOST(ACTTRK); PBIOSS(ACTSEC); PBIOSA(ACTDMA); WRSEC:=PBIOWS; END; FUNCTION RDSEC:BYTE; (* Cteni sektoru *) LABEL 1,2,9,99; VAR RES,RES1:BYTE; PROCEDURE RDTRK; VAR STATUS,I:BYTE; (* cteni pulky stopy ob jeden sektor *) BEGIN I:=1; IF NOT ODD(ACTSEC)THEN I:=2; RES:=0; RES1:=0; REPEAT PBIOST(ACTTRK); PBIOSA(REF(Q^.TRKBUF[(I+1)DIV 2])); PBIOSS(I); STATUS:=PBIORS; IF STATUS<>0 THEN BEGIN RES1:=STATUS; (* chybny alespon jeden sektor *) IF I=ACTSEC THEN RES:=STATUS; (* chybny prave cteny sektor *) END; I:=I+2; UNTIL I>26; END; BEGIN RDSEC:=0; IF (BUFHD^.DSK=ACTDSK)AND(BUFHD^.TRK=MODTRK) THEN GOTO 9; (* buffer je na zacatku fronty *) Q:=BUFHD; 1: P:=Q; Q:=Q^.NXTBUF; (* dalsi buffer *) IF (Q^.DSK=ACTDSK)AND(Q^.TRK=MODTRK) THEN GOTO 2; (* buffer nalezen *) IF Q^.NXTBUF<>NIL THEN GOTO 1; RDTRK; (* prepsan posledni buffer fronty *) IF RES1<>0 THEN BEGIN (* alespon jeden vadny sektor *) Q^.DSK:=FREE; (* stopa se neuklada *) RDSEC:=RES; (* vysledek cteni pozadovaneho sektoru *) MOVE(ACTDMA,REF(Q^.TRKBUF[MODSEC]),SECSZ); GOTO 99 END; Q^.DSK:=ACTDSK; Q^.TRK:=MODTRK; (* doplneni cisla disku a stopy *) 2: (* presunuti vybraneho bufferu na zacatek fronty *) P^.NXTBUF:=Q^.NXTBUF; Q^.NXTBUF:=BUFHD; BUFHD:=Q; 9: (* cteni sektoru z prvniho bufferu *) MOVE(ACTDMA,REF(BUFHD^.TRKBUF[MODSEC]),SECSZ); 99: END; END.