On Sun, 3 Apr 2016 03:52:01 -0700
bilsch <
kin...@comcast.net> wrote:
> I've been trying to use int 13h to get the number of
> sectors on the hard drive.
FYI, not many people have posted here (alt.comp.bios)
over the past 5 years or so, Bill.
I saw your post on comp.lang.asm.x86. Why didn't you
look at Int 13H, AH=41h, BX=55AAh, as I suggested? ...
comp.lang.asm.x86 was a good place to post. alt.lang.asm
and even comp.os.msdos.programmer would've been good places
to post. alt.os.development is probably the best place.
I've added AOD for replies.
> From Ralph Brown List:
> <code>
> AH = 48h
> DL = drive (80h-FFh)
> DS:SI -> buffer for drive parameters
>
> Return:
> CF clear if successful
> AH = 00h
> DS:SI buffer filled
> CF set on error
> AH = error code
>
> Buffer for drive parameters:
>
> Offset Size Description
> 00h WORD (call) size of buffer
> (001Ah for v1.x, 001Eh for v2.x, 42h for v3.0)
> (ret) size of returned data
> 02h WORD information flags (see #00274)
> 04h DWORD number of physical cylinders on drive
> 08h DWORD number of physical heads on drive
> 0Ch DWORD number of physical sectors per track
> 10h QWORD total number of sectors on drive
> 18h WORD bytes per sector
>
> It seems to me, the following code would be the
> correct way to call int 13h ah=48h:
First, are you doing this in a boot loader at 7C00h,
or attempting to call from DOS .com or .exe,
or calling this from an emulator, or calling
this while using Linux or Windows, or using v86 mode?
If in a boot loader at 7C00h, you can call it.
If in DOS as a .com or .exe, DOS may be redirecting
the BIOS IVT interrupt to it's own routines. If
using DOS, you should use DOS routines, not BIOS.
If in an emulator, there could be a bug.
If under another OS like Linux or Windows,
you should not expect to be able to call it.
If you're using v86 mode, you may have problems
with the PM OS or monitor controlling the v86 mode.
> sxbuf times 0x42 db 0 ;bufr for BIOS to fill
Is this buffer actually before your code? Do you
jump to the 'mov' instruction below? I.e., you're
not executing the empty buffer are you? ...
> mov si,sxbuf
What segment value is in DS? It may be wise to make
sure it is below 512KB. Early machines had only 512KB,
while later ones have 640KB. Between 640KB and 1MB+64KB-16,
you have BIOS ROMs, video cards, etc. Above 1MB, shouldn't
be possible, unless you're using "unreal" mode. However,
the BIOS can't use a DS with a limit allowing access above
1MB+64KB-16. I.e., your DS must be a 16-bit RM segment value
below 1MB, actually need to be below 640KB or 512KB, and you
must not be using the "unreal" mode to call the BIOS.
> mov word [si], 0x42
> mov ah,0x48
> mov dl,0x80 ;bit 7 = hard drive
> int 0x13
The buffer value is not necessarily 0x42. It might be
some other value. You should call Int 13h, AH=41h, BX=55AAh
to get the version number in register AH. The AH byte needs
to be zero-extended to word AX and stored at DS:SI.
You also need to check the supported function bitmap
returned in register CX from Int 13h, AH=41h, BX=55AAh
to determine if the 48h call is even supported. Also,
it might be supported, but just not for your device.
Yes, I see that you're attempting to use the most recent
values for modern machines which should in theory work.
However, each BIOS is different. It's better to implement
it fully to get things working. Then, find out why the
abbreviated version doesn't work.
> And the following would be the correct way to read the sectors info:
>
> mov di,0x10 ;offset into sxbuf
> getbuf:
> mov ax,[sxbuf+di]
Location +0x10 is a QWORD or 8 bytes.
AH and AL are 1 byte (available in all modes)
AX is two bytes (available in 16-bit mode) WORD
EAX is four bytes (available in 32-bit mode) DWORD
RAX is eight bytes (available int 64-bit mode) QWORD
> inc di
DI is not scaled by the size of AX like a C variable.
I.e., 'inc di' increments DI by one (1). So, you're
loading two bytes into AX, but moving DI by only one
byte at a time ... You probably want another 'inc'
instruction here.
> cmp di,4
With two 'inc' instructions, you'd need ,8 here.
> je done
> jmp getbuf
> <code>
While you are loading AX with values, I don't see code
to save or use AX within the loop. IIRC, you called
a print loop in your CLAX post.
> but it doesn't work. The call returns:
> CF=1 (failed)
> ah=01 (invalid parameter)
> ax = 0000, 0000, 0000, 0000
I would assume that this is because the 0x42h in DS:SI
buffer is not the correct value, or that DS:SI is not
accessable by the BIOS, or that hard drive 80h is not
actually present.
Perhaps, you're attempting to access a floppy or USB
device or CD-ROM/DVD-ROM?
A floppy device can't be on 80h or higher. A USB device
can only be 80h if it was the boot device and is being
emulated by BIOS as a hard disk. IIRC, a CD-ROM or
DVD-ROM can never be 80h, it must be secondary, e.g., 81h.
Also, note that some BIOS calls need you to explicitly
set CF via STC before being called. Another option would
be that AH or other register is being corrupted somehow,
e.g., use of a debugger or emulator.
> I've tried variations, but none work. I've tried it on five
> relatively new (last 5 years) computers - never works.
>
> How do you do it?
I haven't, but some on alt.os.development have recently.
There was a short competition, IIRC, which used Int 13h
BIOS disk routines. I added AOD to the reply newsgroups.
Other questions:
What value does Int 13h, AH=41h, BX=55AAh
return in in register CX?
This word value has a bitmap which indicates
which "IBM/MS INT 13 Extensions" are supported
by the BIOS. Bit 1, 2, and 3 are listed as
extended, removable, and enhanced, respectively.
48h is listed for all three. 48h description
is as an extension, so, I'd suspect bit 1 to
be set.
What value does Int 13h, AH=41h, BX=55AAh
return in in register AH?
This byte value should be filled in to the first
word of the DS:SI buffer for Int 13h, AH=48h.
Int 13h, AH=48h, indicates that some BIOSes
need word at DS:[SI+2] set to 0000h. So, you
should set both the version number word and
clear the next word in 'sxbuf'.
Is your DS:SI buffer placed below 1MB, preferably
below 640K or 512K? Can you confirm the DS:SI
segment:offset?
Are you initializing the USB controllers? If so,
you'll lose access to a USB boot device that is
being emulated by the BIOS as a hard disk.
If RBIL is not providing enough information,
you can search for the Phoenix Enhanced Disk
Drive Specifications. There are a few versions.
Rod Pemberton