Additional BrokenThorn Issue?

All about the OSDev Wiki. Discussions about the organization and general structure of articles and how to use the wiki. Request changes here if you don't know how to use the wiki.
Post Reply
pretzelpirate
Posts: 2
Joined: Fri Sep 11, 2020 8:06 pm

Additional BrokenThorn Issue?

Post by pretzelpirate »

I don't see it listed here, but I thought I'd have someone check that the issue is with the page and not me: https://wiki.osdev.org/Brokenthorn%27s_Known_Bugs

In OSDev6, BrokenThorn says the LBA to CHS conversion formulas are:
absolute sector = (LBA % sectors per track) + 1
absolute head = (LBA / sectors per track) % number of heads
absolute track = LBA / (sectors per track * number of heads)
link: http://www.brokenthorn.com/Resources/OSDev6.html

I believe the "absolute track" formula is incorrect and the correct set of equations should be:
absolute sector = (LBA % sectors per track) + 1
absolute head = (LBA / sectors per track) % number of heads
absolute track = (LBA / sectors per track) / number of heads
Adding this would reduce confusion with people wondering why the code never multiplies by "number of heads".

I don't have permissions to edit the Wiki yet, but if this looks correct, I can add the reference.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Additional BrokenThorn Issue?

Post by alexfru »

There is no difference?

Try this code:

Code: Select all

#include <stdio.h>

int main(void)
{
  int a, b, c;
  puts("Begin...");
  for (a = 0; a < 128; a++)
    for (b = 1; b < 128; b++)
      for (c = 1; c < 128; c++)
      {
        int r0 = (a / b) / c;
        int r1 = a / (b * c);
        if (r0 != r1)
          printf("(%d / %d) / %d != %d / (%d * %d)\n", a, b, c, a, b, c);
        //printf(".");
      }
  puts("End.");
  return 0;
}
Output:
Begin...
End.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Additional BrokenThorn Issue?

Post by nullplan »

The two are identical. Unless I missed something, dividing by a product is the same as dividing by each of the factors. Mathematically:

Code: Select all

a / b / c = (a / b) / c = (a / b) * (1 / c) = (a * 1) / (b * c)
That doesn't hold with integer division in C, yes, because of the round-off error introduced in step 2, but the ends still apply. I am sure, someone better versed in number theory than I could prove this proposition. But for now I have simply written a program to prove it for me within the range given and it failed to find any counter examples. And that is good enough for me.
pretzelpirate wrote:I don't have permissions to edit the Wiki yet, but if this looks correct, I can add the reference.
Enter your user control panel, click "user groups", click "Wiki", and click "Join". Done.
Carpe diem!
pretzelpirate
Posts: 2
Joined: Fri Sep 11, 2020 8:06 pm

Re: Additional BrokenThorn Issue?

Post by pretzelpirate »

It looks like you're all correct, and I should avoid posting late at night.

I don't quite understand why BrokenThorn used a less obvious formula that didn't match the specific steps that were being done in code, but perhaps this post will help other people who wonder why the code and comments don't match.

Thanks everyone!
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Additional BrokenThorn Issue?

Post by nullplan »

pretzelpirate wrote:I don't quite understand why BrokenThorn used a less obvious formula
Probably a micro-optimization. This way avoids one division, and some programmers, particularly low-level OS programmers, have a pathological aversion to division, believing it to be slow. In this case, though, when you are trying to access a floppy drive, a division is going to be the least of your worries, timewise.
Carpe diem!
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Additional BrokenThorn Issue?

Post by Octocontrabass »

It could be left over from analyzing a hard disk bootloader that uses only 16-bit instructions. It's possible for (LBA / sectors per track) to overflow a 16-bit DIV instruction in cases where (LBA / (sectors per track * number of heads)) would not.
Post Reply