Help with CHS code

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Hanz
Member
Member
Posts: 29
Joined: Sun Mar 09, 2014 10:14 am

Help with CHS code

Post by Hanz »

I'm writing 16 bit operating system in assembly (nasm). It's my second kernel in real mode. I'm trying to write working implementation of disk driver, but my code throws an error every time. I have read the wiki page (http://wiki.osdev.org/ATA_in_x86_RealMo ... ended_Mode) many times, but it does not mention this error. I have also noticed that extended LBA mode doesn't work with VirtualBox.

I set all values by hand like this:

Code: Select all

mov ah, 0x02
mov al, 0x01
mov ch, 0x00
mov cl, 0x0B
mov dh, 0x00
mov dl, 0x00
mov bx, 0x00
mov es, bx
mov bx, 0x1000
int 0x13
jc .error
But int 0x13 sets carry flag every time. The code still works well in my boot loader, where it uses LBA2CHS function with LBA address of kernel.
Problem is not with drive number, it is same as in dl and this is just for testing purposes. However, if cl is smaller than 0x0A then code works, but in 0x0A and bigger values of cl int 0x13 sets the carry flag. It looks like 10 is some kind of limit.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help with CHS code

Post by Brendan »

Hi,
Hanz wrote:However, if cl is smaller than 0x0A then code works, but in 0x0A and bigger values of cl int 0x13 sets the carry flag. It looks like 10 is some kind of limit.
According to the BIOS, how many sectors are there per track?

My guess is that the BIOS thinks there's about 9 sectors per track (which would be normal for "standard but ancient" 320 KiB, 360 KiB and 720 KiB floppy disk formats).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Hanz
Member
Member
Posts: 29
Joined: Sun Mar 09, 2014 10:14 am

Re: Help with CHS code

Post by Hanz »

This site (1) said that it is actually 9 sectors per track, and I checked that using the way you linked. (it's 1.44M floppy)
How should I do reading the right sector. Should I use LBA to CHS conversion? I did it manually and ended up with values: (ch = 1, cl = 2), but it reads just zeros from disk and therefore doesn't work. I know that the program I'm trying to load is in location 0x1600 in floppy so it's in sector 11 (0x0B).

1. https://forums.virtualbox.org/viewtopic.php?p=46844
Hanz
Member
Member
Posts: 29
Joined: Sun Mar 09, 2014 10:14 am

Re: Help with CHS code

Post by Hanz »

I checked the CHS values and they are right. Result is still just zeros.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help with CHS code

Post by Brendan »

Hanz wrote:This site (1) said that it is actually 9 sectors per track, and I checked that using the way you linked. (it's 1.44M floppy)
How should I do reading the right sector. Should I use LBA to CHS conversion? I did it manually and ended up with values: (ch = 1, cl = 2), but it reads just zeros from disk and therefore doesn't work. I know that the program I'm trying to load is in location 0x1600 in floppy so it's in sector 11 (0x0B).

1. https://forums.virtualbox.org/viewtopic.php?p=46844
Erm. For the last post on the forums you linked to it says "what you describe (9 sectors, 2 heads and you can add: 40 tracks) is indeed the 720k format". 1440 KiB (what I think you're talking about) is not the same as 720 KiB (what the poster on the virtualbox forums is talking about). Also note that the poster on the virtualbox forums was wrong anyway, and a 720 KiB disk has 80 cylinders and not 40 cylinders (e.g. 9 sectors per track * 2 heads * 80 cylinders * 512 bytes per sector = 740 KiB).

Offset 0x1600 on the floppy would be "LBA sector number 11". For a 1440 KiB floppy (e.g. 18 sectors per track * 2 heads * 80 cylinders * 512 bytes per sector = 740 KiB) this would be cylinder 0, head 0, sector 12. For a 720 KiB floppy (e.g. 9 sectors per track * 2 heads * 80 cylinders * 512 bytes per sector = 740 KiB) it would be cylinder 0, head 1, sector 3.

However; I still think the BIOS is assuming the floppy disk has 9 sectors per track (there's no other explanation for the symptoms you're reporting); which means that there's no way the BIOS thinks the disk is 1440 KiB. Please note that what the BIOS thinks the disk is and what the disk actually is may be completely different.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Hanz
Member
Member
Posts: 29
Joined: Sun Mar 09, 2014 10:14 am

Re: Help with CHS code

Post by Hanz »

Thanks. Very much.

That calculation
Brendan wrote: For a 720 KiB floppy (e.g. 9 sectors per track * 2 heads * 80 cylinders * 512 bytes per sector = 740 KiB) it would be cylinder 0, head 1, sector 3.
was right. I just have to fix my LBA to CHS function.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help with CHS code

Post by Brendan »

Hi,
Hanz wrote:That calculation
Brendan wrote: For a 720 KiB floppy (e.g. 9 sectors per track * 2 heads * 80 cylinders * 512 bytes per sector = 740 KiB) it would be cylinder 0, head 1, sector 3.
was right. I just have to fix my LBA to CHS function.
Are you sure?

More likely, you have to figure out why the BIOS thinks the floppy is an ancient 720 KiB floppy and fix that instead. ;)

Also note that your CHS code should be using values directly from the floppy disk's BPB (specifically, the "physical sectors per track" and "number of heads" fields). That way, the same code should work perfectly fine on any floppy disk (from 320 KiB all the way up to 2880 KiB), as long as whatever formats the disk sets the BPB fields properly.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: Help with CHS code

Post by glauxosdev »

I think that values in BPB will still be wrong, as we don't know if BIOS uses actual CHS values.
Maybe it is better to use int 0x13 / ah=0x08 to see what BIOS thinks about CHS.
Then, you will need to use a LBA->CHS algorithm, based on returned from int 0x13 values.

Code: Select all

    .get_parameters:
        mov dl, byte [bootdev]
        mov ah, 08h
        int 13h
        and cx, 3Fh ; save max sectors
        mov [maxsect], cx
        add dh, 1 ; save max heads
        mov byte [maxhead], dh
        
    .calculate_sector:
        mov ax, word [lba] ; get lba sector
        mov dx, 0
        div word [maxsect] ; divide lba with max sectors
        add dl, 1 ; take the remainder, sectors start at 1
        mov cl, dl ; sector is in cl
        
    .calculate_head:
        mov ax, word [lba] ; get lba sector
        mov dx, 0
        div word [maxsect] ; divide lba with max sectors
        mov dx, 0
        div word [maxhead] ; divide quotient with heads
        mov dh, dl ; take the remainder, head is in dh
        
    .calculate_cylinder:
        mov ch, al ; take the quotient, cylinder is in ch
I hope it will help you, but please, don't copy-paste! :)
Hanz
Member
Member
Posts: 29
Joined: Sun Mar 09, 2014 10:14 am

Re: Help with CHS code

Post by Hanz »

Hi again.

Thanks for the answers. I fixed my LBAtoCHS function. The only problem was that I assumed that value of SectorsPerTrack was 18, because many tutorials said that.
glauxosdev wrote: Maybe it is better to use int 0x13 / ah=0x08 to see what BIOS thinks about CHS.
I will look at that.
glauxosdev wrote: I hope it will help you, but please, don't copy-paste! :)
Don't worry, I can code assembly, just had problem with that constant.
Post Reply