home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / FLOPPIES / FDFORM16.ZIP / DISKIO.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-10-26  |  11.8 KB  |  376 lines

  1. {$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S-,V-}
  2.  
  3. UNIT diskio;
  4.  
  5. INTERFACE
  6.  
  7. USES dos;
  8.  
  9. CONST Read58: ARRAY[0..5] OF Byte =(
  10.  
  11.   $CD,$25,                                                                 {  INT  25H            }
  12.   $59,                                                                     {  POP  CX             }
  13.   $CA,$02,$00);                                                            {  RETF 2              }
  14.  
  15.   Write58: ARRAY[0..5] OF Byte =(
  16.  
  17.     $CD,$26,                                                               {  INT  26H            }
  18.     $59,                                                                   {  POP  CX             }
  19.     $CA,$02,$00);                                                          {  RETF 2              }
  20.  
  21. TYPE Split      = RECORD
  22.                     O: Word;
  23.                     S: Word;
  24.                   END;
  25.  
  26. TYPE filtyp     = FILE OF ARRAY[0..511] OF Byte;
  27.      fileptr    = ^filtyp;
  28.      boottyp    = ARRAY[36..511] OF Byte;
  29.  
  30. TYPE bpbtyp     =  RECORD
  31.                      jmp: ARRAY[1..3] OF Byte;                     {Die ersten drei Bytes für JUMP}
  32.                      oem: ARRAY[1..8] OF Char;                                        {OEM-Eintrag}
  33.                      bps: Word;                                                  {Bytes pro Sektor}
  34.                      spc: Byte;                                              {Sektoren pro Cluster}
  35.                      res: Word;                                                     {BOOT-Sektoren}
  36.                      fat: Byte;                                                  {Anzahl der FAT's}
  37.                      rde: Word;                                          {Basisverzeichniseinträge}
  38.                      sec: Word;                                       {Gesamtsektoren der Diskette}
  39.                      mds: Byte;                                                  {Media-Deskriptor}
  40.                      spf: Word;                                                  {Sektoren pro FAT}
  41.                      spt: Word;                                                 {Sektoren pro Spur}
  42.                      hds: Word;                                                            {Seiten}
  43.                      shh: Longint;                                            {Versteckte Sektoren}
  44.                      lsc: Longint;                     {Anzahl der Sektoren bei großen Partitionen}
  45.                      boot_code: boottyp;                                     {Puffer für BOOT-Code}
  46.                    END;
  47.  
  48.       dos4rw    = RECORD                                                   {Disk Read/Write Packet}
  49.                     sector   : LongInt;                                     {für Partitionen >=32M}
  50.                     count    : Word;
  51.                     Transfer : Pointer;
  52.                   END;
  53.  
  54. TYPE  SectorTyp = Object
  55.                     data: Pointer;
  56.                     Start: LongInt;
  57.                     datalen: Word;
  58.                     Constructor init(VAR allocated: Boolean);
  59.                     PROCEDURE Error(lw,rw,err:Byte; VAR er:Boolean; Sector:Longint); virtual;
  60.                     PROCEDURE DiskRw(rw,lw:Byte; Sector:LongInt; Count:Byte; Transfer:Pointer);
  61.                     PROCEDURE Readx(lw: Byte; x: LongInt);
  62.                     PROCEDURE Writex(lw: Byte; x: LongInt);
  63.                     Destructor Done;
  64.                   END;
  65.  
  66.  
  67. TYPE CylTyp    = Object (SectorTyp)
  68.                    Constructor init(spcyl: Word; VAR allocated: Boolean);
  69.                    PROCEDURE Readx(lw: Byte; x: Word);
  70.                    PROCEDURE Writex(lw: Byte; x: Word);
  71.                  END;
  72.  
  73.  
  74. TYPE BootSecTyp = Object(SectorTyp)
  75.                     bpb: ^bpbtyp;
  76.                     status: Word;
  77.                     Media: Byte;
  78.                     UnknownDrive: Boolean;
  79.                     dos4: Boolean;
  80.                     Constructor init(VAR allocated: Boolean);
  81.                     PROCEDURE Readx(lw: Byte);
  82.                     PROCEDURE Writex(lw: Byte);
  83.                   END;
  84.  
  85. TYPE STyp       = ARRAY[0..0] OF ^SectorTyp;
  86.      CTyp       = ARRAY[0..0] OF ^CylTyp;
  87.      Smtyp      = ^Styp;
  88.      Cmtyp      = ^CTyp;
  89.  
  90.  
  91.  
  92. VAR BootSec         : BootSecTyp;
  93.   old58             : Pointer;
  94.   maxsec            : Word;
  95.   maxcyl            : Word;
  96.  
  97.  
  98.   PROCEDURE CheckDrive(lw:Byte; VAR Status:Word; VAR error1:Boolean; VAR Media:Byte);
  99.   PROCEDURE DeallocCyl(Var Cylmem:Cmtyp; Stop:Word);
  100.   PROCEDURE DeallocSec(Var Secmem:Smtyp; Stop:Word);
  101.   FUNCTION AllocCyl(VAR Cylmem:Cmtyp; Stop:Word): Word;
  102.   FUNCTION AllocSec(VAR secmem:Smtyp; stop:Word): Word;
  103.   FUNCTION ReadKey: Char;
  104.  
  105. IMPLEMENTATION
  106.  
  107.   FUNCTION ReadKey:Char;
  108.   VAR r: Registers;
  109.   BEGIN
  110.     WITH r DO BEGIN
  111.       ah:=8;
  112.       msdos(r);
  113.       ReadKey:=chr(r.al);
  114.     END;
  115.   END;
  116.  
  117.   PROCEDURE Sectortyp.error(lw,rw,err:Byte; VAR er:Boolean; Sector:Longint);
  118.   VAR chx: Char;
  119.   BEGIN
  120.     WITH BootSec DO BEGIN
  121.       WriteLn;
  122.       IF rw=0 THEN
  123.         Write('Read')
  124.       ELSE
  125.         Write('Write');
  126.       Write('-Error Drive ',chr(lw+$40),': ');
  127.       CASE err OF
  128.         $00: Write('Disk is write protected');
  129.         $01: Write('Unknown unit');
  130.         $02: Write('Drive not ready');
  131.         $03: Write('Unknown command');
  132.         $04: Write('Bad CRC');
  133.         $05: Write('Bad request structure length');
  134.         $06: Write('Seek error');
  135.         $07: Write('Unknown media type');
  136.         $08: Write('Sector not found');
  137.         $09: Write('Printer out of paper');
  138.         $0A: Write('Write fault');
  139.         $0B: Write('Read fault');
  140.         $0C: Write('General failure');
  141.         $0D: Write('Sharing violation');
  142.         $0E: Write('Lock violation');
  143.         $0F: Write('Invalid disk change');
  144.         $10: Write('FCB unavailable');
  145.         $11: Write('Sharing buffer overflow');
  146.         ELSE Write('Unknown error');
  147.       END;
  148.       Writeln('.');
  149.       Write('Error ',err,': Sector: ',Sector,' ');
  150.       IF Sector=0 THEN
  151.         WriteLn('BOOT-Sector')
  152.       ELSE BEGIN
  153.         IF (Sector>=1) and (Sector<=bpb^.spf) THEN
  154.           WriteLn('FAT 1');
  155.         IF (Sector>=bpb^.spf+1) and (sector<=Longint(bpb^.spf) shl 1) THEN
  156.           WriteLn('FAT 2');
  157.       END;
  158.       REPEAT
  159.         Write('(A)bort, (R)etry, (I)gnore ? ');
  160.         chx:=Upcase(ReadKey); WriteLn(chx);
  161.       UNTIL chx IN ['A','I','R'];
  162.       CASE chx OF
  163.         'A': Halt(255);
  164.         'I': BEGIN
  165.                er:=False;
  166.              END;
  167.         'R': er:=True;
  168.       END;
  169.     END;
  170.   END;
  171.  
  172.   Constructor SectorTyp.init(VAR allocated: Boolean);
  173.   BEGIN
  174.     allocated:=True;
  175.     IF MaxAvail<512 THEN allocated:=False;
  176.     IF allocated THEN BEGIN
  177.       GetMem(self.data,512);
  178.       datalen:=512;
  179.     END;
  180.   END;
  181.  
  182.   PROCEDURE SectorTyp.DiskRw(rw,lw:Byte; Sector:Longint; Count:Byte; Transfer:Pointer);
  183.   VAR regs: registers;
  184.  
  185.   VAR er    : Boolean;
  186.     i       :  Word;
  187.     rwpacket:  dos4rw;
  188.  
  189.   BEGIN
  190.     WITH regs DO BEGIN
  191.       GetIntVec($58,old58);
  192.       al:=lw-1;
  193.       IF NOT(BootSec.dos4) THEN BEGIN                                      {Parameter für DOS 2.00-3.30}
  194.         dx:=sector;
  195.         cx:=count;
  196.         bx:=LongInt(Transfer) AND $ffff;
  197.         ds:=LongInt(Transfer) SHR 16;
  198.       END ELSE BEGIN                                    {Parameter ab DOS 4.00 und COMPAQ DOS 3.31}
  199.         cx:=$FFFF;
  200.         rwpacket.sector:=sector;
  201.         rwpacket.count:=count;
  202.         rwpacket.Transfer:=Transfer;
  203.         ds:=Seg(rwpacket);
  204.         bx:=Ofs(rwpacket);
  205.       END;
  206.       IF rw=0 THEN SetIntVec($58,@Read58) ELSE SetIntVec($58,@Write58);
  207.       intr($58,regs);
  208.       IF (FCarry AND Flags) <> 0 THEN
  209.         FOR i:=0 TO Count-1 DO
  210.           REPEAT
  211.             al:=lw-1;
  212.             IF NOT(BootSec.dos4) THEN BEGIN
  213.               dx:=Sector+i;
  214.               cx:=1;
  215.               bx:=LongInt(Transfer) AND $ffff;
  216.               ds:=(LongInt(Transfer) SHR 16)+(i SHL 5);
  217.             END ELSE BEGIN
  218.               cx:=$FFFF;
  219.               rwpacket.sector:=Sector+i;
  220.               rwpacket.count:=1;
  221.               rwpacket.Transfer:=ptr((Longint(Transfer) SHR 16)+(i SHL 5),
  222.                                      LongInt(Transfer) and $ffff);
  223.               ds:=Seg(rwpacket);
  224.               bx:=Ofs(rwpacket);
  225.             END;
  226.             IF rw=0 THEN SetIntVec($58,@Read58) ELSE SetIntVec($58,@Write58);
  227.             intr($58,regs);
  228.             SetIntVec($58,old58);
  229.             er:=False;
  230.             IF (FCarry AND Flags) <> 0 THEN error(lw,rw,regs.al,er,Sector+i);
  231.           UNTIL NOT er;
  232.       SetIntVec($58,old58);
  233.     END;
  234.   END;
  235.  
  236.   PROCEDURE SectorTyp.Readx(lw: Byte; x: LongInt);
  237.   BEGIN
  238.     self.DiskRw(0,lw,x,1,self.data);
  239.   END;
  240.  
  241.   PROCEDURE SectorTyp.Writex(lw: Byte; x: LongInt);
  242.   BEGIN
  243.     self.DiskRw(1,lw,x,1,self.data);
  244.   END;
  245.  
  246.   Constructor CylTyp.init(spcyl: Word; VAR allocated: Boolean);
  247.   BEGIN
  248.     allocated:=True;
  249.     datalen:=spcyl SHL 9;
  250.     IF MaxAvail<datalen THEN allocated:=False;
  251.     IF allocated THEN BEGIN
  252.       GetMem(self.data,datalen);
  253.     END;
  254.   END;
  255.  
  256.   PROCEDURE CylTyp.Readx(lw: Byte; x:Word);
  257.   BEGIN
  258.     self.DiskRw(0,lw,LongInt(x)*(datalen SHR 9),datalen SHR 9,self.data);
  259.   END;
  260.  
  261.   PROCEDURE CylTyp.Writex(lw: Byte; x:Word);
  262.   BEGIN
  263.     self.DiskRw(1,lw,LongInt(x)*(datalen SHR 9),datalen SHR 9,self.data);
  264.   END;
  265.  
  266.   Constructor BootSecTyp.init(VAR allocated: Boolean);
  267.   BEGIN
  268.     allocated:=True;
  269.     IF MaxAvail<512 THEN allocated:=False;
  270.     IF allocated THEN BEGIN
  271.       GetMem(self.data,512);
  272.       self.bpb:=self.data;
  273.       datalen:=512;
  274.     END;
  275.   END;
  276.  
  277.   PROCEDURE BootSecTyp.Readx(lw: Byte);
  278.   BEGIN
  279.     CheckDrive(lw,self.status,self.UnknownDrive,self.Media);
  280.     self.dos4:=false;
  281.     if not(UnknownDrive) and ((self.status and $9202)=2) then
  282.       self.dos4:=true;
  283.     if not(UnknownDrive) and ((self.status and $9200)=0) then
  284.     self.DiskRw(0,lw,0,1,self.data);
  285.   END;
  286.  
  287.   PROCEDURE BootSecTyp.Writex(lw: Byte);
  288.   BEGIN
  289.     self.DiskRw(1,lw,0,1,self.data);
  290.   END;
  291.  
  292.   Destructor SectorTyp.Done;
  293.   BEGIN
  294.     FreeMem(self.data,datalen);
  295.   END;
  296.  
  297.   FUNCTION AllocSec(VAR secmem:Smtyp; Stop:Word): Word;
  298.   VAR i: Word;
  299.     ok: Boolean;
  300.   BEGIN
  301.     GetMem(secmem,(Stop+1)*4);
  302.     FOR i:=0 to Stop do Secmem^[i]:=NIL;
  303.     i:=0;
  304.     REPEAT
  305.       IF (4512>MaxAvail) OR (secmem^[i]<>NIL) THEN
  306.         ok:=False
  307.       ELSE BEGIN
  308.         New(secmem^[i],init(ok));
  309.         IF ok THEN Inc(i);
  310.       END;
  311.     UNTIL NOT(ok) OR (i>stop);
  312.     Dec(i);
  313.     AllocSec:=i;
  314.   END;
  315.  
  316.   FUNCTION AllocCyl(VAR Cylmem:Cmtyp; Stop:Word): Word;
  317.   VAR i: Word;
  318.     ok: Boolean;
  319.   BEGIN
  320.     GetMem(cylmem,(Stop+1)*4);
  321.     FOR i:=0 to Stop do Cylmem^[i]:=NIL;
  322.     i:=0;
  323.     REPEAT
  324.       IF (((BootSec.bpb^.spt*BootSec.bpb^.hds) SHL 9)+4000>MaxAvail) OR
  325.       (cylmem^[i]<>NIL) THEN
  326.         ok:=False
  327.       ELSE BEGIN
  328.         New(cylmem^[i],init(BootSec.bpb^.spt*BootSec.bpb^.hds,ok));
  329.         IF ok THEN Inc(i);
  330.       END;
  331.     UNTIL NOT(ok) OR (i>stop);
  332.     Dec(i);
  333.     AllocCyl:=i;
  334.   END;
  335.  
  336.   PROCEDURE DeallocCyl(Var Cylmem:Cmtyp; Stop:Word);
  337.   VAR i: Word;
  338.   BEGIN
  339.     FOR i:=0 TO stop DO BEGIN
  340.       Dispose(cylmem^[i],Done);
  341.     END;
  342.     FreeMem(cylmem,(Stop+1)*4);
  343.   END;
  344.  
  345.   PROCEDURE DeallocSec(Var Secmem:Smtyp; Stop:Word);
  346.   VAR i: Word;
  347.   BEGIN
  348.     FOR i:=0 TO stop DO BEGIN
  349.       Dispose(secmem^[i],Done);
  350.     END;
  351.     FreeMem(secmem,(Stop+1)*4);
  352.   END;
  353.  
  354.   PROCEDURE CheckDrive(lw:Byte; VAR Status:Word; VAR error1:Boolean; VAR Media:Byte);
  355.   VAR regs: registers;
  356.     driveinfo : ARRAY[0..48] OF Byte;
  357.   BEGIN
  358.     WITH regs DO BEGIN
  359.       ax:=$4409;
  360.       bl:=lw;
  361.       bh:=0;
  362.       intr($21,regs);
  363.       error1:=(FCarry AND Flags) <> 0;
  364.       Status:=dx;
  365.       ax:=$440d;
  366.       cx:=$860;
  367.       bl:=lw;
  368.       bh:=0;
  369.       dx:=Ofs(driveinfo);
  370.       ds:=Seg(driveinfo);
  371.       intr($21,regs);
  372.       Media:=driveinfo[1];
  373.     END;
  374.   END;
  375.  
  376. END.