MConnor
asked on
Disk Parameter Code
I have some assembly used within Pascal to get the size of the hard disk as follows;
function GetGeometry(Drive: Byte; var cyls, heads, sects: Word): Integer;
var Regs: Registers;
begin
regs.ah := 8;
regs.dl :=Drive or $80;
Intr($13, regs);
cyls := (((regs.cl shl 2) and $300) or regs.ch) + 1;
heads := regs.dh + 1;
sects := regs.cl and $3F;
GetGeometry:=regs.ax and $FF00;
if regs.flags and 1 <> 0 then
GetGeometry:=-1;
end;
MB: (sect*heads*cyls)/2048
This unfortunatley only works upto 8gb, I've done some searching and found changing the interrupt 13
call to 48h should return me the information. I don't know how to access the informatin tho' as it is returned differently than above.
Can anyone post me some assembly/comment to help?
As It is quite urgent I am offering 500 points to a correct working solution.
Mike
function GetGeometry(Drive: Byte; var cyls, heads, sects: Word): Integer;
var Regs: Registers;
begin
regs.ah := 8;
regs.dl :=Drive or $80;
Intr($13, regs);
cyls := (((regs.cl shl 2) and $300) or regs.ch) + 1;
heads := regs.dh + 1;
sects := regs.cl and $3F;
GetGeometry:=regs.ax and $FF00;
if regs.flags and 1 <> 0 then
GetGeometry:=-1;
end;
MB: (sect*heads*cyls)/2048
This unfortunatley only works upto 8gb, I've done some searching and found changing the interrupt 13
call to 48h should return me the information. I don't know how to access the informatin tho' as it is returned differently than above.
Can anyone post me some assembly/comment to help?
As It is quite urgent I am offering 500 points to a correct working solution.
Mike
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Dimitry, I had seen both links hence I know I need int13 ah=48h. The code I posted origonally uses int13 ah=8 and this works fine for disks <7.8gb this returns nice easy register entries for me to read.
ah=48h returns something else which I don't understand.
This essentially is my question, how do I read/interpret what int13h ah=48h returns?
If I can get an answer to that the points are yours (I don't hold points back like your last posted link).
Mike
ah=48h returns something else which I don't understand.
This essentially is my question, how do I read/interpret what int13h ah=48h returns?
If I can get an answer to that the points are yours (I don't hold points back like your last posted link).
Mike
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Unfortunately I can't now write in Pascal, but the code C below shows how to use INT 13h, function 48h. It works properly for my computer, but I suspect that for different BIOSes it may work not properly. If you can't compile it, give me your e-mail, I'll send you executable.
/*------------------------ ---------- ---------- ---------- -*/
#include <stdio.h>
#include <dos.h>
/*------------------------ ---------- ---------- ---------- -*/
#define DISK 0x13
#define CF 1
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct {
DWORD lowSecNum;
DWORD highSecNum;
} QWORD;
typedef struct {
WORD bufSize; /* (001Ah for v1.x, 001Eh for v2.x, 42h for v3.0) */
WORD infoFlags; /* (see #00274) */
DWORD cylNum; /* number of physical cylinders on drive */
DWORD headNum; /* number of physical heads on drive */
DWORD secPerTrack; /* number of physical sectors per track */
QWORD secNum; /* total number of sectors on drive */
WORD bytesPerSec; /* bytes per sector */
/*---v2.0+ ---*/
DWORD confParam; /* -> EDD configuration parameters (see #00278) */
/*---v3.0 ---*/
WORD sign;
BYTE length;
BYTE reserved0[3];
BYTE nameBus[4]; /* ASCIZ name of host bus ("ISA" or "PCI") */
BYTE nameType[8]; /* ASCIZ name of interface type */
BYTE intPath[8];
BYTE devPath[8];
BYTE reserved1;
BYTE checksum;
} DevParam48;
DevParam48 devParam;
/*------------------------ ---------- ---------- ---------- -*/
int getDriveParam( unsigned short driveNo, void far *buf )
{ /* Send get Drive Parameters command to INT 13 */
struct REGPACK sreg;
sreg.r_ax = 0x4800; /* Get Drive Parameters */
sreg.r_dx = driveNo; /* Drive: 0x80 */
sreg.r_si = FP_OFF( buf );
sreg.r_ds = FP_SEG( buf );
intr(DISK, &sreg);
if( sreg.r_flags & CF )
return( 1 );
return( 0 );
}
/*------------------------ ---------- ---------- ---------- -*/
int main()
{
DWORD numOfMeg = 0L;
devParam.bufSize = 0x1A;
if( getDriveParam( 0x80, (void far *)&devParam ) != 0 ) {
printf("Error Get Drive Parameters\n");
return( 1 );
}
printf("Get Drive Parameters:\n");
numOfMeg = devParam.secNum.lowSecNum / 2048;
printf(" HD size = %ld Mb\n", numOfMeg);
return( 0 );
}
/*------------------------
#include <stdio.h>
#include <dos.h>
/*------------------------
#define DISK 0x13
#define CF 1
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct {
DWORD lowSecNum;
DWORD highSecNum;
} QWORD;
typedef struct {
WORD bufSize; /* (001Ah for v1.x, 001Eh for v2.x, 42h for v3.0) */
WORD infoFlags; /* (see #00274) */
DWORD cylNum; /* number of physical cylinders on drive */
DWORD headNum; /* number of physical heads on drive */
DWORD secPerTrack; /* number of physical sectors per track */
QWORD secNum; /* total number of sectors on drive */
WORD bytesPerSec; /* bytes per sector */
/*---v2.0+ ---*/
DWORD confParam; /* -> EDD configuration parameters (see #00278) */
/*---v3.0 ---*/
WORD sign;
BYTE length;
BYTE reserved0[3];
BYTE nameBus[4]; /* ASCIZ name of host bus ("ISA" or "PCI") */
BYTE nameType[8]; /* ASCIZ name of interface type */
BYTE intPath[8];
BYTE devPath[8];
BYTE reserved1;
BYTE checksum;
} DevParam48;
DevParam48 devParam;
/*------------------------
int getDriveParam( unsigned short driveNo, void far *buf )
{ /* Send get Drive Parameters command to INT 13 */
struct REGPACK sreg;
sreg.r_ax = 0x4800; /* Get Drive Parameters */
sreg.r_dx = driveNo; /* Drive: 0x80 */
sreg.r_si = FP_OFF( buf );
sreg.r_ds = FP_SEG( buf );
intr(DISK, &sreg);
if( sreg.r_flags & CF )
return( 1 );
return( 0 );
}
/*------------------------
int main()
{
DWORD numOfMeg = 0L;
devParam.bufSize = 0x1A;
if( getDriveParam( 0x80, (void far *)&devParam ) != 0 ) {
printf("Error Get Drive Parameters\n");
return( 1 );
}
printf("Get Drive Parameters:\n");
numOfMeg = devParam.secNum.lowSecNum / 2048;
printf(" HD size = %ld Mb\n", numOfMeg);
return( 0 );
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ping
What's wrong with Borlands DriveSize?
It's really good assembly!
Try to throw an eye with a Debugger on it!
Make it Like this :
Uses {win}Dos;
...
Writeln('Size of actual Drive:',DiskSize(0):16);
...
It's really good assembly!
Try to throw an eye with a Debugger on it!
Make it Like this :
Uses {win}Dos;
...
Writeln('Size of actual Drive:',DiskSize(0):16);
...
recommend -- split to all participanting Experts
ASKER
Mike