home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MADTRB15.ZIP / INT25.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1985-08-02  |  6.8 KB  |  204 lines

  1. { These two functions allow you to call MS-DOS interrupts 25H and 26H.  They
  2.   can't be called with Turbo Pascal's built in Intr procedure because they
  3.   leave the flags register on the stack, in violation of 8086 programming
  4.   techniques.
  5.  
  6.   Interrupt 25H is called Absolute Disk Read, while 26H is Absolute Disk
  7.   Write.  The functions ReadSectors and WriteSectors respectively allow you to
  8.   call these interrupts.  This provides a very low level interface to the disk
  9.   drives.  Because of this, THESE FUNCTIONS SHOULD BE USED WITH EXTREME
  10.   CAUTION, and only if you are sure you know what you are doing.
  11.  
  12.   Both functions are called with the same parameters:
  13.     Buffer: a buffer large enough to hold NumberSectors 512 byte sectors.
  14.     Drive: the drive number.  0 is A:, 1 is B:, and so on.
  15.     NumberSectors: the number of sectors to transfer.
  16.     LogicalSector: the first logical sector number to transfer.
  17.  
  18.   Be sure that Buffer is large enough to hold 512*NumberSectors bytes of data.
  19.   Failure to do so will surely lead to bugs that are difficult to solve.
  20.  
  21.   The integer return value is the error code returned by MS-DOS.  0 indicates
  22.   a successful transfer.  All other values are errors; see a DOS Technical
  23.   Reference Manual for translations.
  24.  
  25.   A small example program is provided.  It is a minimal disk editor and is
  26.   intended as an example only, though it provides the basis for a complete
  27.   disk editor/utility.  (This is a challenge to you hackers).  The example is
  28.   commented out -- you must remove the line with the (* on it.
  29.  
  30.   -  Bela Lubkin
  31.      71016,1573
  32.      5/28/85
  33.  
  34. }
  35.  
  36. {*$C-}
  37. { Remove the leading * for better keyboard response in the example program }
  38.  
  39. Function __ReadWriteSectors(Var Buffer;
  40.                             Drive, NumberSectors, LogicalSector: Integer;
  41.                             WriteFlag: Byte): Integer;
  42.   Var Result: Integer;
  43.   Begin
  44.     Result:=0;
  45.     Inline($8A/$86/ Drive /           {       MOV  AL,[BP+Drive]             }
  46.            $8B/$8E/ NumberSectors /   {       MOV  CX,[BP+NumberSectors]     }
  47.            $8B/$96/ LogicalSector /   {       MOV  DX,[BP+LogicalSector]     }
  48.            $55/                       {       PUSH BP                        }
  49.            $1E/                       {       PUSH DS                        }
  50.            $C5/$9E/ Buffer /          {       LDS  BX,[BP+Buffer]            }
  51.            $80/$BE/ WriteFlag /$01/   {       CMP  BYTE PTR [BP+WriteFlag],1 }
  52.            $74/$04/                   {       JE   Write                     }
  53.            $CD/$25/                   {       INT  25H                       }
  54.            $EB/$02/                   {       JMP  WrapUp                    }
  55.            $CD/$26/                   {Write: INT 26H                        }
  56.            $5B/                       {WrapUp:POP  BX     ;Dispose of flags  }
  57.            $1F/                       {       POP  DS                        }
  58.            $5D/                       {       POP  BP                        }
  59.            $73/$04/                   {       JNB  Ok                        }
  60.            $89/$86/ Result            {       MOV  [BP+Result],AX            }
  61.            );                         {Ok:                                   }
  62.     __ReadWriteSectors:=Result;
  63.   End;
  64.  
  65. Function ReadSectors(Var Buffer;
  66.                      Drive, NumberSectors, LogicalSector: Integer): Integer;
  67.   Begin
  68.     ReadSectors:=
  69.       __ReadWriteSectors(Buffer,Drive,NumberSectors,LogicalSector,0);
  70.   End;
  71.  
  72. Function WriteSectors(Var Buffer;
  73.                       Drive, NumberSectors, LogicalSector: Integer): Integer;
  74.   Begin
  75.     WriteSectors:=
  76.       __ReadWriteSectors(Buffer,Drive,NumberSectors,LogicalSector,1);
  77.   End;
  78.  
  79. { Example program.  Delete next line to enable it: }
  80. (*
  81.  
  82. {$R+}
  83.  
  84. Type
  85.   Str=String[4];
  86.  
  87. Function Int2Hex2(B: Byte): Str;
  88.   Const H: Array [0..15] Of Char='0123456789ABCDEF';
  89.   Begin
  90.     Int2Hex2:=H[B Shr 4]+H[B And 15];
  91.   End;
  92.  
  93. Function Int2Hex4(I: Integer): Str;
  94.   Const H: Array [0..15] Of Char='0123456789ABCDEF';
  95.   Begin
  96.     Int2Hex4:=H[I Shr 12]+H[(I Shr 8) And 15]+H[(I Shr 4) And 15]+H[I And 15];
  97.   End;
  98.  
  99. Function Hex2Int1(C: Char): Byte;
  100.   Begin
  101.     Case Upcase(C) Of
  102.       '0'..'9': Hex2Int1:=Ord(C) And 15;
  103.       'A'..'F': Hex2Int1:=Ord(C) And 15+9;
  104.       Else Hex2Int1:=0;
  105.      End;
  106.   End;
  107.  
  108. Function Hex2Int4(S: Str; Default: Integer): Integer;
  109.   Var I: Integer;
  110.   Begin
  111.     If S='' Then Hex2Int4:=Default
  112.     Else
  113.      Begin
  114.       I:=0;
  115.       While S<>'' Do
  116.        Begin
  117.         I:=I Shl 4 + Hex2Int1(S[1]);
  118.         Delete(S,1,1);
  119.        End;
  120.       Hex2Int4:=I;
  121.      End;
  122.   End;
  123.  
  124. Procedure ShowSector(Var S);
  125.   Var Buffer: Array [0..31,0..15] Of Byte Absolute S;
  126.       I,J: Integer;
  127.       B: Byte;
  128.   Begin
  129.     For I:=0 To 31 Do
  130.      Begin
  131.       Write(Int2Hex4(I Shl 4),' |  ');
  132.       For J:=0 To 15 Do
  133.        Begin
  134.         Write(Int2Hex2(Buffer[I,J]),' ');
  135.         If J And 3=3 Then Write(' ');
  136.        End;
  137.       Write('| ');
  138.       For J:=0 To 15 Do
  139.        Begin
  140.         B:=Buffer[I,J];
  141.         If B<127 Then NormVideo
  142.         Else LowVideo;
  143.         B:=B And $7F;
  144.         If B<32 Then B:=Ord('.');
  145.         Write(Chr(B));
  146.        End;
  147.       NormVideo;
  148.       WriteLn;
  149.      End;
  150.   End;
  151.  
  152. Var
  153.   Buffer: Array [0..511] Of Byte;
  154.   DR,LS,Result,C: Integer;
  155.   W: Char;
  156.   V: Str;
  157.   Changed: Boolean;
  158.  
  159. Begin
  160.   FillChar(Buffer,SizeOf(Buffer),'z');
  161.   Repeat
  162.     DR:=-1;
  163.     Write('Enter the drive # to read (CR to end): ');
  164.     ReadLn(DR);
  165.     If DR In [0..25] Then
  166.      Begin
  167.       Write('Enter the logical sector # to read: ');
  168.       ReadLn(LS);
  169.       Result:=ReadSectors(Buffer,DR,1,LS);
  170.       WriteLn('Result code = ',Result);
  171.       Changed:=False;
  172.       Repeat
  173.         ShowSector(Buffer);
  174.         Write('Enter the number of the byte to change (0-1FF, CR to end): ');
  175.         ReadLn(V);
  176.         C:=Hex2Int4(V,-1);
  177.         If (C>0) And (C<512) Then
  178.          Begin
  179.           Write('Enter new value [',Int2Hex2(Buffer[C]),']: ');
  180.           ReadLn(V);
  181.           If Length(V)>1 Then
  182.             If V[1] In ['''','"'] Then Buffer[C]:=Ord(V[2])
  183.             Else Buffer[C]:=Hex2Int4(V,Buffer[C])
  184.           Else Buffer[C]:=Hex2Int4(V,Buffer[C]);
  185.           Changed:=True;
  186.          End
  187.         Else C:=-1;
  188.       Until C=-1;
  189.       If Changed Then
  190.        Begin
  191.         Write('Write changes back to drive ',DR,', logical sector #',LS,' (Y/N)? ');
  192.         ReadLn(W);
  193.         If Upcase(W)='Y' Then
  194.          Begin
  195.           Result:=WriteSectors(Buffer,DR,1,LS);
  196.           WriteLn('Result code = ',Result);
  197.          End;
  198.        End;
  199.      End
  200.     Else DR:=-1;
  201.   Until DR=-1;
  202. End.
  203. (**)
  204.