home *** CD-ROM | disk | FTP | other *** search
-
- The following example routines are public domain programs that
- have been uploaded to our Forum on CompuServe. As a courtesy to
- our users that do not have immediate access to CompuServe,
- Technical Support distributes these routines free of charge.
-
- However, because these routines are public domain programs, not
- developed by Borland International, we are unable to provide any
- technical support or assistance using these routines. If you need
- assistance using these routines, or are experiencing
- difficulties, we recommend that you log onto CompuServe and
- request assistance from the Forum members that developed these
- routines.
-
- Turbo Pascal's Intr procedure cannot call MS-DOS interrupts 25H
- and 26H because they do not leave the CPU flags on the stack.
- This set of functions allows you to call those interrupts, which
- are Absolute Disk Read and Absolute Disk Write, by using the
- following functions ReadSectors and WriteSectors, respectively.
-
- Both functions are called with the same parameters:
- Buffer: a buffer large enough to hold NumberSectors 512
- byte sectors.
- Drive: the drive number. 0 is A:, 1 is B:, and so on.
- NumberSectors: the number of sectors to transfer.
- LogicalSector: the first logical sector number to transfer.
-
- Be sure that the Buffer is large enough to hold 512 times
- NumberSectors bytes of data. Failure to do so will surely lead
- to bugs that are difficult to solve.
-
- The integer return value is the error code returned by MS-DOS.
- "0" indicates a successful transfer, all other values are errors.
- See a DOS Technical Reference Manual for translations.
-
- A small sample program is provided. It is a minimal disk editor
- and is intended as an example only, though it provides the basis
- for a complete disk editor/utility. The example is commented out
- -- you must remove the line with the "(*" on it.
-
- USE WITH CAUTION!
-
- }
-
- {$C-}
- { Remove the leading * for better keyboard response in the
- example program }
-
- Function __ReadWriteSectors(Var Buffer;
- Drive, NumberSectors, LogicalSector: Integer;
- WriteFlag: Byte): Integer;
- Var Result: Integer;
- Begin
- Result:=0;
- Inline($8A/$86/ Drive / { MOV AL,[BP+Drive] }
- $8B/$8E/ NumberSectors / { MOV CX,[BP+NumberSectors] }
- $8B/$96/ LogicalSector / { MOV DX,[BP+LogicalSector] }
- $55/ { PUSH BP }
- $1E/ { PUSH DS }
- $C5/$9E/ Buffer / { LDS BX,[BP+Buffer] }
- $80/$BE/ WriteFlag /$01/ { CMP BYTE PTR [BP+WriteFlag],1
- }
- $74/$04/ { JE Write
- }
- $CD/$25/ { INT 25H
- }
- $EB/$02/ { JMP WrapUp
- }
- $CD/$26/ {Write: INT 26H
- }
- $5B/
- {WrapUp:POP BX ;Dispose of flags }
- $1F/ { POP DS }
- $5D/ { POP BP }
- $73/$04/ { JNB Ok }
- $89/$86/ Result { MOV [BP+Result],AX }
- ); {Ok: }
- __ReadWriteSectors:=Result;
- End;
-
- Function ReadSectors(Var Buffer; Drive, NumberSectors,
- LogicalSector: Integer): Integer;
- Begin
- ReadSectors:=
- __ReadWriteSectors(Buffer,Drive,NumberSectors,
- LogicalSector,0);
- End;
-
- Function WriteSectors(Var Buffer; Drive, NumberSectors,
- LogicalSector: Integer): Integer;
- Begin
- WriteSectors:=
- __ReadWriteSectors(Buffer,Drive,NumberSectors,
- LogicalSector,1);
- End;
-
- { Example program. Delete next line to enable it: }
- (*
-
- {$R+}
-
- Type
- Str=String[4];
-
- Function Int2Hex2(B: Byte): Str;
- Const H: Array [0..15] Of Char='0123456789ABCDEF';
- Begin
- Int2Hex2:=H[B Shr 4]+H[B And 15];
- End;
-
- Function Int2Hex4(I: Integer): Str;
- Const H: Array [0..15] Of Char='0123456789ABCDEF';
- Begin
- Int2Hex4:=H[I Shr 12]+H[(I Shr 8) And 15]+
- H[(I Shr 4) And 15]+H[I And 15];
- End;
-
- Function Hex2Int1(C: Char): Byte;
- Begin
- Case Upcase(C) Of
- '0'..'9': Hex2Int1:=Ord(C) And 15;
- 'A'..'F': Hex2Int1:=Ord(C) And 15+9;
- Else Hex2Int1:=0;
- End;
- End;
-
- Function Hex2Int4(S: Str; Default: Integer): Integer;
- Var I: Integer;
- Begin
- If S='' Then Hex2Int4:=Default
- Else
- Begin
- I:=0;
- While S<>'' Do
- Begin
- I:=I Shl 4 + Hex2Int1(S[1]);
- Delete(S,1,1);
- End;
- Hex2Int4:=I;
- End;
- End;
-
- Procedure ShowSector(Var S);
- Var Buffer: Array [0..31,0..15] Of Byte Absolute S;
- I,J: Integer;
- B: Byte;
- Begin
- For I:=0 To 31 Do
- Begin
- Write(Int2Hex4(I Shl 4),' | ');
- For J:=0 To 15 Do
- Begin
- Write(Int2Hex2(Buffer[I,J]),' ');
- If J And 3=3 Then Write(' ');
- End;
- Write('| ');
- For J:=0 To 15 Do
- Begin
- B:=Buffer[I,J];
- If B<127 Then NormVideo
- Else LowVideo;
- B:=B And $7F;
- If B<32 Then B:=Ord('.');
- Write(Chr(B));
- End;
- NormVideo;
- WriteLn;
- End;
- End;
-
-
- Var
- Buffer: Array [0..511] Of Byte;
- DR,LS,Result,C: Integer;
- W: Char;
- V: Str;
- Changed: Boolean;
-
- Begin
- FillChar(Buffer,SizeOf(Buffer),'z');
- Repeat
- DR:=-1;
- Write('Enter the drive # to read (CR to end): ');
- ReadLn(DR);
- If DR In [0..25] Then
- Begin
- Write('Enter the logical sector # to read: ');
- ReadLn(LS);
- Result:=ReadSectors(Buffer,DR,1,LS);
- WriteLn('Result code = ',Result);
- Changed:=False;
- Repeat
- ShowSector(Buffer);
- Write('Enter the number of the byte to change ');
- Write(' (0-1FF, CR to end): ');
- ReadLn(V);
- C:=Hex2Int4(V,-1);
- If (C>0) And (C<512) Then
- Begin
- Write('Enter new value [',Int2Hex2(Buffer[C]),']: ');
- ReadLn(V);
- If Length(V)>1 Then
- If V[1] In ['''','"'] Then Buffer[C]:=Ord(V[2])
- Else Buffer[C]:=Hex2Int4(V,Buffer[C])
- Else Buffer[C]:=Hex2Int4(V,Buffer[C]);
- Changed:=True;
- End
- Else C:=-1;
- Until C=-1;
-
- If Changed Then
- Begin
- Write('Write changes back to drive ',DR,',');
- Write ('logical sector #',LS,' (Y/N)? ');
- ReadLn(W);
- If Upcase(W)='Y' Then
- Begin
- Result:=WriteSectors(Buffer,DR,1,LS);
- WriteLn('Result code = ',Result);
- End;
- End;
- End
- Else DR:=-1;
- Until DR=-1;
- End.
- (**)
-
-