home *** CD-ROM | disk | FTP | other *** search
- {... so there I was, sitting in a bar when a known C Programmer }
- {comes up to me and sniggers "still doing it in Pascal eh?" }
- {"Yup" I replied, and tossed the bartender another hundred. }
- {"Yeah well, when you're ready For a Real language, only C has }
- {all the aces." }
- {I'm a Pascal Programmer. I don't have to take that. "Such as?"}
- {I hoped he'd bite and he did. }
- {"Such as disk sector reading and writing For starters." }
- {"Well I hope you're not bluffin', 'cause here's a trick that }
- {I'll bet you ain't covered." }
- {I pulled it out With a swish and laid it on the table. "Even }
- {provides support For >32M volumes, which the C run-time library }
- {manual Forgets to tell you it won't do." }
- {"Huh? Where?" }
- {"Right here" I said. "Just where it says... }
-
- Program AbsReadTest;
-
- {This Program demonstrates a C-style absread and absWrite For TP.}
- {As is, it reads the boot sector off drive A:, and optionally }
- {Writes it out to the very last sector on drive A: (assumes 1.2Meg}
- {This Program IS dangerous, and is released to the public domain.}
- {I take no responsibility For use or misuse, deliberate or }
- {accidental, of this Program or any Program which Uses the }
- {techniques described herein. }
-
- {Author: Mitch Davis 3:634/384.6 +61-3-890-2062 v1.0 28-Jun-92. }
-
- Var bp:Pointer; {Will point to the buffer For the sector data}
-
- Function absread (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;
-
- {Works just like the C runtime one- including being restricted to 32M volumes!}
-
- {drive is a Character, nsects is the number of sectors, and lsect is the first}
- {sector. buffer points to the buffer you'd like filled from disk. Function }
- {returns True if there was an error, or False if all went well. }
-
- Var kludgebuff:Array [0..$1f] of Byte; {Read Ralf Brown's interrupt listing}
- kludgePtr:Pointer; {Int 25h - ES:[BP+1E] may change }
-
- begin
- kludgePtr := @kludgebuff;
- absread := True;
- if drive < 'A' then Exit;
- if drive > 'Z' then Exit;
- Asm
- push es
- push bp
- push di
- les di, kludgePtr
- mov al, drive { Gets the passed parameter. }
- and al, 1fh { Cvt from ASCII to drive num }
- dec al { Adjust because A: is drive 0 }
- mov cx, nsects { number of sectors to read }
- mov dx, lsect { starting at sector.. }
- push ds
- lds bx, buffer { Get the address of the buffer }
- mov bp, di
- push si
- int 25h { Do the drive read. }
- pop si { Remove the flags int 25h leaves on stack}
- pop si
- pop ds
- pop di
- pop bp
- pop es
- jc @1
- mov ah, 0 { No errors, so set Function to False }
- @1:
- mov @result, ah
- end;
- end;
-
- Function absWrite
- (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;
-
- {Works just like the C one - including being restricted to 32M volumes!}
-
- {drive is a Character, nsects is the number of sectors, and lsect is the first}
- {sector. buffer points to the buffer you'd like filled from disk. Function }
- {returns True if there was an error, or False if all went well. }
-
- Var kludgebuff:Array [0..$1f] of Byte;
- kludgePtr:Pointer;
-
- begin
- kludgePtr := @kludgebuff;
- absWrite := True;
- if drive < 'A' then Exit;
- if drive > 'Z' then Exit;
- Asm
- push es
- push bp
- push di
- les di, kludgePtr
- mov al, drive { Gets the passed parameter. }
- and al, 1fh { Cvt from ASCII to drive num }
- dec al { Adjust because A: is drive 0 }
- mov cx, nsects { number of sectors to Write }
- mov dx, lsect { starting at sector.. }
- push ds
- lds bx, buffer { Get the address of the buffer }
- mov bp, di
- push si
- int 26h { Do the drive Write. }
- pop si { Remove the flags int 26h leaves on stack}
- pop si
- pop ds
- pop di
- pop bp
- pop es
- jc @1
- mov ah, 0
- @1:
- mov @result, ah
- end;
- end;
-
- Function absLread (drive:Char; nsects:Word; lsect:LongInt;
- buffer:Pointer):Boolean;
-
- {This Function reads sectors on disks which have the >32M style made popular}
- {by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+. }
-
- Var packet:Array [0..9] of Byte; {disk request packet - see Ralf Brown's ints}
-
- begin
- absLread := True;
- if drive < 'A' then Exit;
- if drive > 'Z' then Exit;
- Asm
- mov ax, Word ptr lsect {Get the LSB of the start sector}
- mov Word ptr packet[0], ax {Store it in the packet }
- mov ax, Word ptr lsect + 2 {Get the MSB of the start sector}
- mov Word ptr packet[2], ax {Store this one too. }
- mov ax, nsects {How many sectors to read }
- mov Word ptr packet[4], ax
- {Insert the Pointer to the data buffer into the packet}
- push bp ; push ds
- lds dx, buffer { Get the address of the buffer }
- mov Word ptr packet[6], dx
- mov dx, ds
- mov Word ptr packet[8], dx
- mov al, drive { Gets the passed parameter. }
- and al, 1fh { Cvt from ASCII to drive num }
- dec al { Adjust because A: is drive 0 }
- int 25h { Do the drive read. }
- pop si { Remove the flags int 25h leaves on stack}
- pop ds
- pop bp
- jc @1
- mov ah, 0
- @1:
- mov @result, ah
- end;
- end;
-
- Function absLWrite (drive:Char; nsects:Word; lsect:LongInt;
- buffer:Pointer):Boolean;
-
- {This Function Writes sectors on disks which have the >32M style made popular}
- {by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+. }
-
- Var packet:Array [0..9] of Byte;
-
- begin
- absLWrite := True;
- if drive < 'A' then Exit;
- if drive > 'Z' then Exit;
- Asm
- mov ax, Word ptr lsect
- mov Word ptr packet[0], ax
- mov ax, Word ptr lsect + 2
- mov Word ptr packet[2], ax
- mov ax, nsects
- mov Word ptr packet[4], ax
- push bp ; push ds
- lds dx, buffer
- mov Word ptr packet[6], dx
- mov dx, ds
- mov Word ptr packet[8], dx
- mov al, drive { Gets the passed parameter. }
- and al, 1fh { Cvt from ASCII to drive num }
- dec al { Adjust because A: is drive 0 }
- int 26h { Do the drive Write. }
- pop si { Remove the flags int 26h leaves on stack}
- pop ds
- pop bp
- jc @1
- mov ah, 0
- @1:
- mov @result, ah
- end;
- end;
-
- Function LongNeeded (drive:Char):Boolean;
-
- {This Function returns True or False depending on whether the long versions}
- {of absread/absWrite needed to be invoked; that is, it's a drive Formatted }
- {in the Dos 4+ >32M style. }
- {I strongly suggest you see Ralf Brown's interrupt listing For int21h subfs}
- {440d and 53 - they'll tell you all you know to understand the guts of this}
- {Function. }
-
- Label Escape;
-
- Var drivestats:Array [0..31] of Byte;
-
- begin
- LongNeeded := False;
- if drive < 'A' then Exit;
- if drive > 'Z' then Exit;
- Asm
- push ds
- mov dx, ss
- mov ds, dx
- lea dx, drivestats
- mov bl, drive { Gets the passed parameter. }
- and bl, 1fh { Cvt from ASCII to drive num }
- mov ax, 440Dh
- mov cx, 0860h
- int 21h
- jc Escape
- mov ax, Word ptr drivestats[0Fh]
- or ax, ax
- jnz Escape
- mov @Result, 1
- Escape:
- pop ds
- end;
- end;
-
- begin
- getmem (bp,2048);
- Writeln (LongNeeded ('A'));
- Writeln (LongNeeded ('C'));
- Writeln (absread ('A',1,0,bp));
- (* Writeln (absWrite ('A',1,2399,bp)); *) {remove the comments at your own}
- {risk!!!}
- freemem (bp,2048);
- end.
-
- {So I bought him a drink. The poor guy looked like he needed one....}