Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> |
|---|---|
| Newsgroups | alt.comp.bios, alt.os.development |
| Subject | Re: How to use BIOS int 13h ah=48h ? |
| Date | 2016-04-03 17:36 -0400 |
| Organization | Aioe.org NNTP Server |
| Message-ID | <20160403173650.55074eb8@_> (permalink) |
| References | <ndqsef$9r8$1@dont-email.me> |
Cross-posted to 2 groups.
On Sun, 3 Apr 2016 03:52:01 -0700 bilsch <king621@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
Back to alt.comp.bios | Previous | Next — Previous in thread | Next in thread | Find similar
How to use BIOS int 13h ah=48h ? bilsch <king621@comcast.net> - 2016-04-03 03:52 -0700
Re: How to use BIOS int 13h ah=48h ? Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-04-03 17:36 -0400
Re: How to use BIOS int 13h ah=48h ? bilsch <king621@comcast.net> - 2016-04-05 05:34 -0700
Re: How to use BIOS int 13h ah=48h ? "Benjamin David Lunt" <zfysz@fysnet.net> - 2016-04-05 12:53 -0700
Re: How to use BIOS int 13h ah=48h ? Rod Pemberton <NoHaveNotOne@bcczxcfre.cmm> - 2016-04-06 00:10 -0400
THANKS FOR INFO & SUGGESTIONS bilsch <king621@comcast.net> - 2016-04-08 07:49 -0700
csiph-web